携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
前言
本文旨在针对一些在Android开发中比较常见的容器类进行用法介绍和推荐使用场景。
SparseArray
简介
一个名为Array的以整型为Key的Map。
实现
SparseArray内部维护两个数组:一个类型为整型的Key数组;一个Object类型的Value数组。配对的Key和Value在各自的数组中的下标是相同的。
线程安全: 否。
查找方式: 二分查找。
删除实现: 内部有一个名为DELECT的Object对象。当需要删除某个value时并不直接删除该value,而是将value数组的对应位置的值指向DELECT对象,并将mGarbage标志位置为true。删除不会直接触发容量变动,而是在其他操作(例如size()、查找key等)后判断mGarbage是否为true,为true则进行垃圾清理。
优缺点
由于SparseArray是Map的用法,所以优缺点大多与HashMap对比。
-
优点:
- 因为不需要自动装箱以及无需依赖额外的Entry对象,所以内存性能优于HashMap。
- 可以通过Key以及Index来查找Value,更加灵活。
- Key的取值无需连续。(与直接使用Object数组相比)
-
缺点:
- 由于固定的查找方法为二分法,数据量过大(K级)时查找性能反而会比HashMap低。
使用场景
- 错误码(整型)与描述的映射。
- 自定义排序的顺序储存。
ArrayMap
简介
数组实现的Map。
实现
ArrayMap顾名思义是使用数组来实现的:一个储存Key的Object数组;一个储存Value的Object数组。配对的Key和Value在各自的数组中的下标是相同的。
线程安全: 否。
查找方式: 二分查找。
容量实现: 删除Item时会马上缩短数组。
优缺点
同样是跟HashMap进行比较。
-
优点:
- 用数组实现,内存表现由于HashMap。
- 删除Item后立即缩短数组,极大程度节省内存。
-
缺点:
- 由于固定使用二分查找,大数据量时查找性能比HashMap差。
- 由于数组大小经常变动,会有额外的性能开销。
使用场景
满足以下条件的HashMap应用场景:
- 数据量不大(K级)。
- 查找行为多与增删行为。
- 内存占用敏感。
PriorityQueue
简介
自动根据优先级排序的队列,固定从小到大排序。元素间比较有两种方式:自然顺序(要求元素实现Comparable)、排序器排序(需要在初始化时传入Comparator)。
实现
使用平衡二叉树(堆)实现。在增删元素时动态调整堆结构。
线程安全: 否。提供了线程安全版本:PriorityBlockingQueue。
使用场景
- 简单排序场景(基本类型排序,注意固定从小到大)。
- 自定义排序场景(例如请求后台后根据返回结果决定顺序,使用Comparator实现)。
DelayQueue
简介
自动根据剩余时间排序,并只有在元素剩余时间为零的时候才能被取出(take)。元素必须实现Delayed接口。
实现
使用PriorityQueue实现,通过比较剩余时间来进行排序。
线程安全: 是。
使用场景
有即时发布延时执行任务的场景(当然一般也可以用延时发布即时执行的方式实现)。
- 订单支付超时取消。
- 资源过期自动清理。