集合实用程序类 - Java 小酌

集合实用程序类在 JDK 1.2 中添加,最近一次更新是在 JDK 8 中。集合实用程序类提供了一个 API,用于处理集合框架中的类;集合、列表、映射和集。我们来看看。

💡 注意:本文中的示例使用 List,但在大多数情况下,MapSetCollection 和集合框架中的其他类都有补充方法。为简洁起见,只显示 List 示例。

搜索集合

对集合执行的最常见操作之一是搜索其内容。集合实用程序在此提供了多个选项。

集合提供了在已排序集合上执行二分搜索的选项

List<String> advocates = List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai");
Collections.binarySearch(advocates, "Billy");//1

最小值/最大值

如果集合的所有项都实现了 Comparable,则集合具有 min()max(),用于分别根据自然顺序查找集合的最低值和最大值

List<String> advocates = List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai");
Collections.max(advocates);//Nicolai
Collections.min(advocates);//Ana

频率

集合可以使用 frequency 搜索项在集合中出现的次数

List<String> advocates = List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai");
Collections.frequency(advocates, "Denys");//1

比较集合

集合还具有比较两个 List 以查找匹配项的选项。有 indexOfSubList(),它将在子列表与目标 List 匹配时返回第一个实例的索引,以及 lastIndexOfSubList(),它执行相同操作,但针对最后一次出现。在这两种情况下,如果找不到匹配项,将返回 -1

还有 disjoint(),它比较两个集合中包含的项。如果两个集合之间没有公共项,则返回 true,如果一个集合中的任何项出现在目标集合中,则返回 false。以下是所有示例

List<String> advocates = List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai");
List<String> doubleAdvocates = List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai",
		"Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai");
List<String> managers = List.of("Chad", "David", "Sharat");
List<String> someAdvocates = List.of("Denys", "Heather");
Collections.indexOfSubList(doubleAdvocates, someAdvocates);//2 (finds first occurrence) 
Collections.lastIndexOfSubList(doubleAdvocates, someAdvocates);//7 (finds last occurrence) 
Collections.disjoint(advocates, someAdvocates);//false
Collections.disjoint(advocates, managers);//true

向集合中添加和复制集合

对于向集合中添加、复制集合或在某些情况下创建集合,集合实用程序有几种解决方案。

全部添加

要向集合中添加多个项,可以使用 addAll()。此 addAll() 优于大多数 Collection 类型实现的 addAll(),因为它具有空安全性

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));
Collections.addAll(advocates, "Jack", "Jill");//Nicolai, Nicolai, Nicolai, Nicolai, Nicolai, Nicolai, Jack, Jill

复制

集合实用程序还可以将一个集合的内容复制到另一个集合中。目标集合需要与源集合大小相同或更大

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));
List<String> advocatesCopy = new ArrayList<>(List.of("Blank","Blank","Blank","Blank","Blank","Blank", "Blank"));
Collections.copy(advocatesCopy, advocates);//Ana, Billy, Denys, Heather, Jim, Nicolai, Blank

n 份副本

集合可用于创建一个不可变的 List,该列表填充有传递值的 n 个副本

List<String> copies = Collections.nCopies(3, "Billy");//Billy, Billy, Billy

填充

使用 fill() 的集合可以用传递的值填充现有集合中的所有值

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));
Collections.fill(advocates, "Billy");//Billy, Billy, Billy, Billy, Billy, Billy

替换

如果你需要替换 List 中的特定值,可以使用 replaceAll(),它会用替换值替换目标值的全部实例

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));
Collections.replaceAll(advocates, "Billy", "Nicolai");//Nicolai, Nicolai, Nicolai, Nicolai, Nicolai, Nicolai

重新排序集合

如果你需要更改集合的顺序,集合实用工具有很多选项。

排序

要按其自然顺序对集合进行排序,有:sort(Collection)。集合中的所有项都必须实现 Comparable。或者,如果项未实现 Comparable 或需要不同的顺序,则可以使用 sort(Collection, Comparable)。还有互补的 reverseOrder()Collections.reverseOrder(Comparable),它们会反转自然顺序。最后还有 reverse(Collection)

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));
Collections.sort(advocates);//Ana, Billy, Denys, Heather, Jim, Nicolai
Collections.sort(advocates, Collections.reverseOrder());//Nicolai, Jim, Heather, Denys, Billy, Ana
Comparator<String> reverseString = new Comparator<String>() {
	@Override
	public int compare(String o1, String o2) {return o2.compareTo(o1);}
};
Collections.sort(advocates, Collections.reverseOrder(reverseString));//Ana, Billy, Denys, Heather, Jim, Nicolai Collections.reverse(advocates);//Nicolai, Jim, Heather, Denys, Billy, Ana

旋转

集合还可以按索引旋转 List,如下例所示

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));
Collections.rotate(advocates, 3);//Heather, Jim, Nicolai, Ana, Billy, Denys

交换

如果需要更改特定项的位置,可以使用 swap() 进行更改

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));
Collections.swap(advocates, 0, advocates.size() -1);//Nicolai, Billy, Denys, Heather, Jim, Ana

洗牌

集合还可以使用 shuffle() 随机重新排序 List

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));
Collections.shuffle(advocates, new Random());// [non-stable order]

转换集合

集合还可以帮助将集合从一种类型转换为另一种类型。

已检查

集合可以转换为已检查版本,该版本提供了超出泛型系统提供的保证,即只能添加集合分配类型的项

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));

Collections.checkedList(advocates, String.class);

枚举

集合可以使用 enumeration() 转换为 Enumeration

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));

Collections.enumeration(advocates);

不可修改

集合提供 unmodifiableX() 方法,用于创建提供的集合的不可修改视图。如果对提供的集合进行了更改,则这些更改可能会显示在视图中

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));

Collections.unmodifiableList(advocates);

已同步

集合还可以提供关联集合类型的同步实现

List<String> advocates = new ArrayList<>(List.of("Ana", "Billy", "Denys", "Heather", "Jim", "Nicolai"));

Collections.synchronizedList(advocates);

💡 注意:使用同步集合实现不会对虚拟线程造成问题,因为它们仅保护内存中操作,而不保护 I/O 或其他外部调用,而这些调用通常(长得多)。

集合还可以创建一个不可修改的空集合,如果需要满足方法参数要求,这会很有帮助

Collections.emptyList();

其他方法

集合实用工具提供了一些不完全适合上述类别的其他方法。不过,它们可能值得一试

Collections.asLifoQueue(Deque);
Collections.singleton(T);
Collections.singletonList(T);
Collections.singletonMap(K, V);
Collections.newSetFromMap(Map<E, Boolean>);

其他阅读材料

集合实用工具 JDK 20 JavaDoc

集合框架

编程愉快!