背景
Collections 工具类 JDK 提供的一个工具类,位于 java.util 包下,提供了一系列的静态方法,方便我们对集合进行各种操作,算是集合框架的一个大管家。
实现
排序操作
- reverse(List list):反转顺序
- shuffle(List list):洗牌,将顺序打乱
- sort(List list):自然升序
- sort(List list, Comparator c):按照自定义的比较器排序
- swap(List list, int i, int j):将 i 和 j 位置的元素交换位置
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author 郎家岭伯爵
* @time 2023/1/29 10:28
*/
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("langjialing0");
list.add("langjialing1");
list.add("langjialing2");
list.add("langjialing3");
list.add("langjialing4");
System.out.println("原始顺序:" + list);
// 反转
Collections.reverse(list);
System.out.println("使用Collections反转后:" + list);
// 洗牌
Collections.shuffle(list);
System.out.println("使用Collections洗牌后:" + list);
// 自然升序
Collections.sort(list);
System.out.println("使用Collections自然升序后:" + list);
// 交换顺序
Collections.swap(list, 1, 3);
System.out.println("使用Collections交换顺序后:" + list);
}
}
输出:
原始顺序:[langjialing0, langjialing1, langjialing2, langjialing3, langjialing4]
使用Collections反转后:[langjialing4, langjialing3, langjialing2, langjialing1, langjialing0]
使用Collections洗牌后:[langjialing3, langjialing1, langjialing0, langjialing2, langjialing4]
使用Collections自然升序后:[langjialing0, langjialing1, langjialing2, langjialing3, langjialing4]
使用Collections交换顺序后:[langjialing0, langjialing3, langjialing2, langjialing1, langjialing4]
查找操作
- 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):返回指定对象出现的次数
// 最大元素
System.out.println("最大元素:" + Collections.max(list));
// 最小元素
System.out.println("最小元素:" + Collections.min(list));
// 元素出现的次数
System.out.println("元素出现的次数:" + Collections.frequency(list, "langjialing0"));
// 二分查找:没有经过排序的二分查找的元素是不确定的
Collections.shuffle(list);
System.out.println("未经过排序的二分查找:" + Collections.binarySearch(list, "langjialing2"));
// 二分查找:经过排序后的二分查找的元素是一定的
Collections.sort(list);
System.out.println("经过排序后的二分查找:" + Collections.binarySearch(list, "langjialing2"));
// 填充
Collections.fill(list, "langjialing");
System.out.println("填充后:" + list);
输出:
最大元素:langjialing4
最小元素:langjialing0
元素出现的次数:1
未经过排序的二分查找:-4
经过排序后的二分查找:2
填充后:[langjialing, langjialing, langjialing, langjialing, langjialing]
同步控制
例如 HashMap、ArrayList 是线程不安全的,没法在多线程环境下使用, Collections 工具类中提供了多个 synchronizedXxx
方法,这些方法会返回一个同步的对象,从而解决多线程中访问集合时的安全问题。
使用起来很简单:
List<String> synchronizedList = Collections.synchronizedList(list);
...
synchronized (list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
既然封装类内部已经加了对象锁,为什么外部还要加一层对象锁?
看源码可知,Collections.synchronizedList 中很多方法,比如equals、hasCode、get、set、add、remove、indexOf、lastIndexOf……
都添加了锁,但是 List 中迭代器没有加锁:
Iterator<E> iterator();
因此,迭代器没有加锁,不是线程安全的,所以如果要遍历,还是必须要在外面加一层锁。
使用 Iterator 迭代器的话,似乎也没必要用 Collections.synchronizedList 的方法来包装了,因为反正都是必须要使用 Synchronized 代码块包起来的。
所以总的来说,Collections.synchronizedList 这种做法,适合不需要使用Iterator、对性能要求也不高的场景。
其它操作
-
addAll(Collection<? super T> c, T… elements):往集合中添加元素
-
disjoint(Collection> c1, Collection> c2):判断两个集合是否没有交集
disjoint 方法是判断是否没有交集,而非是否有交集。
// 向集合中添加元素
Collections.addAll(list, "郎家岭0", "郎家岭1", "郎家岭2");
System.out.println("addAll后:" + list);
// 判断集合是否没有交集
List<String> list1 = new ArrayList<>();
list1.add("langjialing");
list1.add("郎家岭0");
System.out.println("是否有交集:" + (Collections.disjoint(list, list1) ? "是":"否"));
输出:
addAll后:[langjialing, langjialing, langjialing, langjialing, langjialing, 郎家岭0, 郎家岭1, 郎家岭2]
是否有交集:否
总结
Collections 工具类常规使用。