ArraySet VS HashSet
最近在阅读Android系统APP“Settings”时,发现了ArraySet类(android.util包,并非java类),在Android使用ArraySet可能会更好的平衡内存性能,但它的效率要低于HashSet,只适合存储上限几百个简单元素的场景。发现此APP使用ArraySet的地方在Settings的启动页SettingsHomepageActivity.java,Settings用ArraySet来保存多个自定义监听类实例,多数同学在相同的场景一般都是习惯用ArrayList(类似场景:ArrayList不如HashSet合适,HashSet在内存方面不如ArraySet),其实在Android Frameworks的很多地方都使用到了ArraySet。
相识接口对比
1、add接口对比
HashSet:
boolean add(E e)
ArraySet:
boolean add(E value)
void addAll(ArraySet<? extends E> array)
boolean addAll(Collection<? extends E> collection)
对比如上,ArraySet的add接口更为丰富
2、remove接口对比
HashSet:
boolean remove(Object o)
ArraySet:
boolean remove(Object object)
boolean removeAll(ArraySet<? extends E> array) boolean removeAll(Collection<?> collection)
E removeAt(int index)
boolean removeIf(Predicate<? super E> filter)
对比如上,ArraySet的remove接口也是更加丰富,其中特别是removeIf可以根据定义好的规则一次性移除,可以解耦代码,简洁代码
内部实现方式
HashSet:借用HashMap,不多说了
ArraySet:核心采用2个数组,一个存对象,一个存对象的hash值
ArraySet如何平衡内存与性能
google为了移动端的内存,也是花了很多心思,比如ArraySet,为了减少一点点内存开销,ArrarySet内部可以自动放大和缩小数组容易,重点缩小,这是很多java类不具备的功能
ArraySet类注释
下面是ArraySet类的注释,里面说到该类的优点和使用场景以及注意事项,也说到与HashSet性能的比较,里面还提到了ArrayMap(下一篇文章再介绍)
/**
* ArraySet is a generic set data structure that is designed to be more memory efficient than a
* traditional {@link java.util.HashSet}. The design is very similar to
* {@link ArrayMap}, with all of the caveats described there. This implementation is
* separate from ArrayMap, however, so the Object array contains only one item for each
* entry in the set (instead of a pair for a mapping).
*
* <p>Note that this implementation is not intended to be appropriate for data structures
* that may contain large numbers of items. It is generally slower than a traditional
* HashSet, since lookups require a binary search and adds and removes require inserting
* and deleting entries in the array. For containers holding up to hundreds of items,
* the performance difference is not significant, less than 50%.</p>
*
* <p>Because this container is intended to better balance memory use, unlike most other
* standard Java containers it will shrink its array as items are removed from it. Currently
* you have no control over this shrinking -- if you set a capacity and then remove an
* item, it may reduce the capacity to better match the current size. In the future an
* explicit call to set the capacity should turn off this aggressive shrinking behavior.</p>
*/