Java 进阶 (三十九)Java 集合类的排序, 查找, 替换操作
一、前言
在 Java 方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList
来表示动态数组。获取到ArrayList
对象后,可以根据Collection
中的方法进行排序,查找,替换操作。而不用在东奔西走的利用什么各种排序算法、正则来实现了。
在进行数组排序时,有时反而会因为参数问题而大费周折。例如,自己在利用快排进行数组排序时,当将参数(int [] a, int left, int right)
改为(ArrayList<Integer> a, int left, int right)
时,在方法体内大费周折。当然,通过阅读源代码也可以看到,这里提到的排序、查找、替换操作实际上是对排序算法、正则的一种封装罢了。
Collections
工具类提供了大量针对Collection/Map
的操作,总体可分为四类,都为静态(static)方法。
二、排序操作(主要针对 List 接口相关)
reverse(List list)
:反转指定 List 集合中元素的顺序;
shuffle(List list)
:对 List 中的元素进行随机排序(洗牌);
sort(List list)
:对 List 里的元素根据自然升序排序;
sort(List list, Comparator c)
:自定义比较器进行排序;
swap(List list, int i, int j)
:将指定 List 集合中 i 处元素和 j 出元素进行交换;
rotate(List list, int distance)
:将所有元素向右移位指定长度,如果 distance 等于 size 那么结果不变;
三、查找和替换(主要针对 Collection 接口相关)
binarySearch(List list, Object key)
:使用二分搜索法,以获得指定对象在 List 中的索引,前提是集合已经排序;
max(Collection coll)
:返回最大元素;
max(Collection coll, Comparator comp)
:根据自定义比较器,返回最大元素;
min(Collection coll)
:返回最小元素;
min(Collection coll, Comparator comp)
:根据自定义比较器,返回最小元素;
fill(List list, Object obj)
:使用指定对象填充;
frequency(Collection Object o)
:返回指定集合中指定对象出现的次数;
replaceAll(List list, Object old, Object new)
:替换;
四、同步控制
Collections
工具类中提供了多个synchronizedXxx
方法,该方法返回指定集合对象对应的同步对象,从而解决多线程并发访问集合时线程的安全问题。HashSet、ArrayList、HashMap
都是线程不安全的,如果需要考虑同步,则使用这些方法。这些方法主要有:synchronizedSet、synchronizedSortedSet、synchronizedList、synchronizedMap、synchronizedSortedMap
。
特别需要指出的是,在使用迭代方法遍历集合时需要手工同步返回的集合。
五、设置不可变集合
Collections
有三类方法可返回一个不可变集合:
emptyXxx()
:返回一个空的不可变的集合对象;
singletonXxx()
:返回一个只包含指定对象的,不可变的集合对象。
unmodifiableXxx()
:返回指定集合对象的不可变视图;
六、其它
disjoint(Collection<?> c1, Collection<?> c2)
- 如果两个指定 collection
中没有相同的元素,则返回 true。
addAll(Collection<? super T> c, T... a)
- 一种方便的方式,将所有指定元素添加到指定 collection 中。
示范:
Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");
Comparator<T> reverseOrder(Comparator<T> cmp)
- 返回一个比较器,它强行反转指定比较器的顺序。如果指定比较器为 null,则此方法等同于 reverseOrder()
(换句话说,它返回一个比较器,该比较器将强行反转实现 Comparable
接口那些对象 collection 上的自然顺序)。
七、集合框架讲解
上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap
等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap
等,而点线边框的是接口,比如Collection,Iterator,List
等。
我们可以看到Collection
是List、Set、Queue
接口的父接口,故该接口中定义的方法可用于操作List、Set、Queue
集合。
发现一个特点,上述所有的集合类,都实现了Iterator
接口,这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()
三种方法。它的一个子接口LinkedIterator
在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()
。也就是说如果是先Iterator
接口,那么在遍历集合中元素的时候,只能往后遍历,被遍历后的元素不会在遍历到,通常无序集合实现的都是这个接口,比如HashSet,HashMap
;而那些元素有序的集合,实现的一般都是LinkedIterator
接口,实现这个接口的集合可以双向遍历,既可以通过next()
访问下一个元素,又可以通过previous()
访问前一个元素,比如ArrayList
。
还有一个特点就是抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作流昂大大降低。
版权声明: 本文为 InfoQ 作者【No Silver Bullet】的原创文章。
原文链接:【http://xie.infoq.cn/article/36f8b9125d38bbc82a3416d68】。文章转载请联系作者。
评论