「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
Collections 是 JDK 提供的一个工具类,位于 java.util 包下,提供了一系列的静态方法,方便我们对集合进行各种骚操作,算是集合框架的一个大管家。
PS:star 这种事,只能求,不求没效果,铁子们,《Java 程序员进阶之路》在 GitHub 上已经收获了 556 枚星标,铁子们赶紧去点点了,冲 600 star!
还记得我们前面讲过的 Arrays 工具类吗?可以回去温习下。
Collections 的用法很简单,在 Intellij IDEA 中敲完 Collections.
之后就可以看到它提供的方法了,大致看一下方法名和参数就能知道这个方法是干嘛的。
为了节省大家的学习时间,我将这些方法做了一些分类,并列举了一些简单的例子。
01、排序操作
reverse(List list)
:反转顺序shuffle(List list)
:洗牌,将顺序打乱sort(List list)
:自然升序sort(List list, Comparator c)
:按照自定义的比较器排序swap(List list, int i, int j)
:将 i 和 j 位置的元素交换位置
来看例子:
1 | java复制代码List<String> list = new ArrayList<>(); |
输出后:
1 | css复制代码原始顺序:[沉默王二, 沉默王三, 沉默王四, 沉默王五, 沉默王六] |
02、查找操作
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 c, Object o)
:返回指定对象出现的次数
来看例子:
1 | java复制代码System.out.println("最大元素:" + Collections.max(list)); |
输出后:
1 | css复制代码原始顺序:[沉默王二, 沉默王三, 沉默王四, 沉默王五, 沉默王六] |
03、同步控制
HashMap 是线程不安全的,这个我们前面讲到了。那其实 ArrayList 也是线程不安全的,没法在多线程环境下使用,那 Collections 工具类中提供了多个 synchronizedXxx 方法,这些方法会返回一个同步的对象,从而解决多线程中访问集合时的安全问题。
使用起来也非常的简单:
1 | java复制代码SynchronizedList synchronizedList = Collections.synchronizedList(list); |
看一眼 SynchronizedList 的源码就明白了,不过是在方法里面使用 synchronized 关键字加了一层锁而已。
1 | java复制代码static class SynchronizedList<E> |
那这样的话,其实效率和那些直接在方法上加 synchronized 关键字的 Vector、Hashtable 差不多(JDK 1.0 时期就有了),而这些集合类基本上已经废弃了,几乎不怎么用。
1 | java复制代码public class Vector<E> |
正确的做法是使用并发包下的 CopyOnWriteArrayList、ConcurrentHashMap。这些我们放到并发编程时再讲。
04、不可变集合
emptyXxx()
:制造一个空的不可变集合singletonXxx()
:制造一个只有一个元素的不可变集合unmodifiableXxx()
:为指定集合制作一个不可变集合
举个例子:
1 | java复制代码List emptyList = Collections.emptyList(); |
这段代码在执行的时候就抛出错误了。
1 | php复制代码Exception in thread "main" java.lang.UnsupportedOperationException |
这是因为 Collections.emptyList()
会返回一个 Collections 的内部类 EmptyList,而 EmptyList 并没有重写父类 AbstractList 的 add(int index, E element)
方法,所以执行的时候就抛出了不支持该操作的 UnsupportedOperationException 了。
这是从分析 add 方法源码得出的原因。除此之外,emptyList 方法是 final 的,返回的 EMPTY_LIST 也是 final 的,种种迹象表明 emptyList 返回的就是不可变对象,没法进行增伤改查。
1 | java复制代码public static final <T> List<T> emptyList() { |
05、其他
还有两个方法比较常用:
addAll(Collection<? super T> c, T... elements)
,往集合中添加元素disjoint(Collection<?> c1, Collection<?> c2)
,判断两个集合是否没有交集
举个例子:
1 | java复制代码List<String> allList = new ArrayList<>(); |
输出后:
1 | css复制代码原始顺序:[沉默王二, 沉默王三, 沉默王四, 沉默王五, 沉默王六] |
整体上,Collections 工具类作为集合框架的大管家,提供了一些非常便利的方法供我们调用,也非常容易掌握,没什么难点,看看方法的注释就能大致明白干嘛的。
不过,工具就放在那里,用是一回事,为什么要这么用就是另外一回事了。能不能提高自己的编码水平,很大程度上取决于你到底有没有去钻一钻源码,看这些设计 JDK 的大师们是如何写代码的,学会一招半式,在工作当中还是能很快脱颖而出的。
恐怕 JDK 的设计者是这个世界上最好的老师了,文档写得不能再详细了,代码写得不能再优雅了,基本上都达到了性能上的极致。
可能有人会说,工具类没什么鸟用,不过是调用下方法而已,但这就大错特错了:如果要你来写,你能写出来 Collections 这样一个工具类吗?
这才是高手要思考的一个问题。
这是《Java 程序员进阶之路》专栏的第 64 篇。Java 程序员进阶之路,风趣幽默、通俗易懂,对 Java 初学者极度友好和舒适😘,内容包括但不限于 Java 语法、Java 集合框架、Java IO、Java 并发编程、Java 虚拟机等核心知识点。
亮白版和暗黑版的 PDF 也准备好了呢,一起成为更好的 Java 工程师,冲!
本文转载自: 掘金