java基础 集合工具类Collections

437 阅读7分钟

集合工具类Collections

集合有许多独立的实用工具程序,在 java.util.Collections 中表示为静态方法。之前已经见过其中一些,例如 addAll()reverseOrder()binarySearch() 。以下是其他内容(同步和不可修改的实用工具程序将在后面的章节中介绍)。在此表中,在需要的时候使用了泛型:

Collectiions操作的方法
方法描述
checkedCollection(Collection c, Class type) checkedList(List list, Class type) checkedMap(Map<K, V> m, Class keyType, Class valueType) checkedSet(Set s, Class type) checkedSortedMap(SortedMap<K, V> m, Class keyType, Class valueType) checkedSortedSet(SortedSet s, Class type)生成 Collection 的动态类型安全视图或 Collection 的特定子类型。 当无法使用静态检查版本时使用这个版本。 这些方法的使用在第九章 多态章节的“动态类型安全”标题下进行了展示。
max(Collection) min(Collection)使用 Collection 中对象的自然比较方法生成参数集合中的最大或最小元素。
max(Collection, Comparator) min(Collection, Comparator)使用 Comparator 指定的比较方法生成参数集合中的最大或最小元素。
indexOfSubList(List source, List target)返回 targetsource 内第一次出现的起始索引,如果不存在则返回 -1。
lastIndexOfSubList(List source, List target)返回 targetsource 内最后一次出现的起始索引,如果不存在则返回 -1。
replaceAll(List list, T oldVal, T newVal)newVal 替换列表中所有的 oldVal
reverse(List)反转列表
reverseOrder() reverseOrder(Comparator)返回一个 Comparator ,它与集合中实现了 comparable 接口的对象的自然顺序相反。第二个版本颠倒了所提供的 Comparator 的顺序。
rotate(List, int distance)将所有元素向前移动 distance ,将尾部的元素移到开头。(译者注:即循环移动)
shuffle(List) shuffle(List, Random)随机置换指定列表(即打乱顺序)。第一个版本使用了默认的随机化源,或者也可以使用第二个版本,提供自己的随机化源。
sort(List) sort(List, Comparator<? super T> c)第一个版本使用元素的自然顺序排序该 List 。第二个版本根据提供的 Comparator 排序。
copy(List<? super T> dest, List<? extends T> src)src 中的元素复制到 dest
swap(List, int i, int j)交换 List 中位置 i 和 位置 j 的元素。可能比你手工编写的速度快。
fill(List<? super T>, T x)x 替换 List 中的所有元素。
nCopies(int n, T x)返回大小为 n 的不可变 List ,其引用都指向 x
disjoint(Collection, Collection)如果两个集合没有共同元素,则返回 true
frequency(Collection, Object x)返回 Collection 中,等于 x 的元素个数。
emptyList() emptyMap() emptySet()返回不可变的空 ListMapSet 。这些是泛型的,因此生成的 Collection 可以被参数化为所需的类型。
singleton(T x) singletonList(T x) singletonMap(K key, V value)生成一个不可变的 ListSetMap ,其中只包含基于给定参数的单个元素。
list(Enumeration e)生成一个 ArrayList ,其中元素为(旧式) EnumerationIterator 的前身)中的元素。用于从遗留代码向新式转换。
enumeration(Collection)为参数集合生成一个旧式的 Enumeration

请注意, min()max() 使用 Collection 对象,而不使用 List ,因此不必担心是否应对 Collection 进行排序。(如前所述,在执行 binarySearch() 之前,将会对 List 或数组进行sort() 排序。)

下面是一个示例,展示了上表中大多数实用工具程序的基本用法:

// collectiontopics/Utilities.java
// Simple demonstrations of the Collections utilities
import java.util.*;

public class Utilities {
  static List<String> list = Arrays.asList(
    "one Two three Four five six one".split(" "));
  public static void main(String[] args) {
    System.out.println(list);
    System.out.println("'list' disjoint (Four)?: " +
      Collections.disjoint(list,
        Collections.singletonList("Four")));
    System.out.println(
      "max: " + Collections.max(list));
    System.out.println(
      "min: " + Collections.min(list));
    System.out.println(
      "max w/ comparator: " + Collections.max(list,
      String.CASE_INSENSITIVE_ORDER));
    System.out.println(
      "min w/ comparator: " + Collections.min(list,
      String.CASE_INSENSITIVE_ORDER));
    List<String> sublist =
      Arrays.asList("Four five six".split(" "));
    System.out.println("indexOfSubList: " +
      Collections.indexOfSubList(list, sublist));
    System.out.println("lastIndexOfSubList: " +
      Collections.lastIndexOfSubList(list, sublist));
    Collections.replaceAll(list, "one", "Yo");
    System.out.println("replaceAll: " + list);
    Collections.reverse(list);
    System.out.println("reverse: " + list);
    Collections.rotate(list, 3);
    System.out.println("rotate: " + list);
    List<String> source =
      Arrays.asList("in the matrix".split(" "));
    Collections.copy(list, source);
    System.out.println("copy: " + list);
    Collections.swap(list, 0, list.size() - 1);
    System.out.println("swap: " + list);
    Collections.shuffle(list, new Random(47));
    System.out.println("shuffled: " + list);
    Collections.fill(list, "pop");
    System.out.println("fill: " + list);
    System.out.println("frequency of 'pop': " +
      Collections.frequency(list, "pop"));
    List<String> dups =
      Collections.nCopies(3, "snap");
    System.out.println("dups: " + dups);
    System.out.println("'list' disjoint 'dups'?: " +
      Collections.disjoint(list, dups));
    // Getting an old-style Enumeration:
    Enumeration<String> e =
      Collections.enumeration(dups);
    Vector<String> v = new Vector<>();
    while(e.hasMoreElements())
      v.addElement(e.nextElement());
    // Converting an old-style Vector
    // to a List via an Enumeration:
    ArrayList<String> arrayList =
      Collections.list(v.elements());
    System.out.println("arrayList: " + arrayList);
  }
}
/* Output:
[one, Two, three, Four, five, six, one]
'list' disjoint (Four)?: false
max: three
min: Four
max w/ comparator: Two
min w/ comparator: five
indexOfSubList: 3
lastIndexOfSubList: 3
replaceAll: [Yo, Two, three, Four, five, six, Yo]
reverse: [Yo, six, five, Four, three, Two, Yo]
rotate: [three, Two, Yo, Yo, six, five, Four]
copy: [in, the, matrix, Yo, six, five, Four]
swap: [Four, the, matrix, Yo, six, five, in]
shuffled: [six, matrix, the, Four, Yo, five, in]
fill: [pop, pop, pop, pop, pop, pop, pop]
frequency of 'pop': 7
dups: [snap, snap, snap]
'list' disjoint 'dups'?: true
arrayList: [snap, snap, snap]
*/复制ErrorOK!

输出解释了每种实用方法的行为。请注意由于大小写的缘故,普通版本的 min()max() 与带有 String.CASE_INSENSITIVE_ORDER 比较器参数的版本的区别。

上面展示了混杂的,下面进行分类一下:

1、排序操作(主要针对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那么结果不变

2、查找和替换(主要针对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 obj):返回指定集合中指定对象出现的次数
replaceAll(List list,Object old,Object new):替换


3、同步控制
Collections工具类提供了多个synchronizedXxx方法,该方法返回指定集合对象对应的同步对象,从而解决多线程并发访问集合时
线程的安全问题。HashSet、ArrayList、HashMap都是线程不安全的,如果需要考虑同步,则使用这些方法。这些方法主要有:synchronizedSet、synchronizedSortedSet、synchronizedList、synchronizedMap、synchronizedSortedMap
特别需要注意:在使用迭代方法遍历集合时需要手工同步返回的集合。{否则会有线程安全的问题}

4、设置不可变得结合
Collections工具类有三种方法返回一个不可变集合
emptyXxx():        返回一个空的不可变的集合对象
singletonXxx():    返回一个只包含指定对象的,不可变的集合对象
unmodifiableXxx(): 返回指定集合对象的不可变视图

5、其它
disjoint(Collections<?>c1,Collections<?>c2) 如果两个指定collection中没有相同的元素,则返回true
addAll(Collection<?super T>c,T...a) 一种方便的方式,将所有指定元素添加到指定collection中
Comparator<T>reverseOrder(Comparator<T>cmp)返回一个比较器,它强行反转指定比较器的顺序。如果指定比较器为null,则
此方法等同于reverseOrder(){返回一个比较器,它对实现 Comparable接口的对象集合施加了 自然排序的相反}
排序和搜索列表

用于执行排序和搜索 List 的实用工具程序与用于排序对象数组的程序具有相同的名字和方法签名,只不过是 Collections 的静态方法而不是 Arrays 。 这是一个使用 Utilities.java 中的 list 数据的示例:

// collectiontopics/ListSortSearch.java
// Sorting/searching Lists with Collections utilities
import java.util.*;

public class ListSortSearch {
  public static void main(String[] args) {
    List<String> list =
      new ArrayList<>(Utilities.list);
    list.addAll(Utilities.list);
    System.out.println(list);
    Collections.shuffle(list, new Random(47));
    System.out.println("Shuffled: " + list);
    // Use ListIterator to trim off last elements:
    ListIterator<String> it = list.listIterator(10);
    while(it.hasNext()) {
      it.next();
      it.remove();
    }
    System.out.println("Trimmed: " + list);
    Collections.sort(list);
    System.out.println("Sorted: " + list);
    String key = list.get(7);
    int index = Collections.binarySearch(list, key);
    System.out.println(
      "Location of " + key + " is " + index +
      ", list.get(" + index + ") = " +
      list.get(index));
    Collections.sort(list,
      String.CASE_INSENSITIVE_ORDER);
    System.out.println(
      "Case-insensitive sorted: " + list);
    key = list.get(7);
    index = Collections.binarySearch(list, key,
      String.CASE_INSENSITIVE_ORDER);
    System.out.println(
      "Location of " + key + " is " + index +
      ", list.get(" + index + ") = " +
      list.get(index));
  }
}
/* Output:
[one, Two, three, Four, five, six, one, one, Two,
three, Four, five, six, one]
Shuffled: [Four, five, one, one, Two, six, six, three,
three, five, Four, Two, one, one]
Trimmed: [Four, five, one, one, Two, six, six, three,
three, five]
Sorted: [Four, Two, five, five, one, one, six, six,
three, three]
Location of six is 7, list.get(7) = six
Case-insensitive sorted: [five, five, Four, one, one,
six, six, three, three, Two]
Location of three is 7, list.get(7) = three
*/复制ErrorOK!

就像使用数组进行搜索和排序一样,如果使用 Comparator 进行排序,则必须使用相同的 Comparator 执行 binarySearch()

该程序还演示了 Collections 中的 shuffle() 方法,该方法随机打乱了 List 的顺序。 ListIterator 是在打乱后的列表中的特定位置创建的,用于从该位置删除元素,直到列表末尾