集合实用程序类 - Java 小酌
Billy Korando,2023 年 6 月 11 日
集合实用程序类在 JDK 1.2 中添加,最近一次更新是在 JDK 8 中。集合实用程序类提供了一个 API,用于处理集合框架中的类;集合、列表、映射和集。我们来看看。
💡 注意:本文中的示例使用 List
,但在大多数情况下,Map
、Set
、Collection
和集合框架中的其他类都有补充方法。为简洁起见,只显示 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>);
其他阅读材料
编程愉快!