Collections集合工具类

一、概述

        Collections类是针对集合操作的工具类,提供了许多静态方法来对Set、List、Map进行操作(排序、查找、填充元素)。通过使用这些方法,可以简化集合操作代码,提高代码的可读性和可靠性。


二、常用方法

1、排序操作:主要有sort()、reverse()、shuffle()、swap()等方法,用于改变集合中元素的顺序。

  •  1)、sort():对集合中的元素进行排序。主要有两种重载形式:
    • Ⅰ、void sort(List<T> list):对指定列表中的元素进行升序排序,但列表中的元素所对应的类必须实现Comparable接口,否则编译不通过。
      public class CollectionsTest {
          public static void main(String[] args) {
              // 1、void sort(List<T> list):对集合中的元素进行排序。
              // 1)、Java内置类的集合进行排序
              List<Integer> list = Arrays.asList(3, 55, 11, 4, 99);
              System.out.println("排序前:" + list); // [3, 55, 11, 4, 99]
              Collections.sort(list);
              System.out.println("排序后:" + list); // [3, 4, 11, 55, 99]
              // 2)、自定义类的集合进行排序:自定义类必须实现Comparable接口
              List<Student> studentList = new ArrayList<>(Arrays.asList(
                      new Student("张三", 24),
                      new Student("李四", 14),
                      new Student("王五", 34)
              ));
              System.out.println("排序前:" + studentList); // [Person{name='张三', age=24}, Person{name='李四', age=14}, Person{name='王五', age=34}]
              Collections.sort(studentList);
              System.out.println("排序后:" + studentList); // [Person{name='李四', age=14}, Person{name='张三', age=24}, Person{name='王五', age=34}]
          }
      }
      
      // 集合元素对应的类需要实现Comparable自然排序接口
      public class Student implements Comparable<Student>{
          private String name;
          private Integer age;
      
          public Student(String name, Integer age) {
              this.name = name;
              this.age = age;
          }
      
          @Override
          public int compareTo(Student o) {
              return this.age.compareTo(o.getAge());
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public Integer getAge() {
              return age;
          }
      
          public void setAge(Integer age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Person{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
    • Ⅱ、void sort(List<T> list, Comparator<? super T> c):使用指定的Comparator比较器对指定列表中的元素进行排序。
      public class CollectionsTest {
          public static void main(String[] args) {
              // 2、 void sort(List<T> list, Comparator<? super T> c):使用指定的Comparator比较器对指定列表进行排序
              // 1)、Java内置类的集合进行排序
              List<Integer> list = Arrays.asList(3, 55, 11, 4, 99);
              System.out.println("排序前:" + list); // [3, 55, 11, 4, 99]
              Collections.sort(list, (o1, o2) -> o1 -o2);
              System.out.println("升序排序后:" + list); // [3, 4, 11, 55, 99]
              Collections.sort(list, (o1, o2) -> o2 -o1);
              System.out.println("降序排序后:" + list); // [99, 55, 11, 4, 3]
              // 2)、自定义类的集合进行排序:自定义类不需要实现Comparable接口
              List<Person> people = new ArrayList<>(Arrays.asList(
                      new Person("张三", 24),
                      new Person("李四", 14),
                      new Person("王五", 34)
              ));
              System.out.println("排序前:" + people); // [Person{name='张三', age=24}, Person{name='李四', age=14}, Person{name='王五', age=34}]
              Collections.sort(people, Comparator.comparingInt(Person::getAge));
              System.out.println("升序排序后:" + people); // [Person{name='李四', age=14}, Person{name='张三', age=24}, Person{name='王五', age=34}]
              Collections.sort(people, Comparator.comparingInt(Person::getAge).reversed());
              System.out.println("降序排序后:" + people); // [Person{name='李四', age=14}, Person{name='张三', age=24}, Person{name='王五', age=34}]
          }
      }
  • 2)、void reverse(List<?> list):反转集合中的元素。
    // void reverse(List<?> list):反转集合中的元素
    List<Integer> list = Arrays.asList(3, 55, 11, 4, 99);
    System.out.println("反转前:" + list); // [3, 55, 11, 4, 99]
    Collections.reverse(list);
    System.out.println("反转后:" + list); // [99, 4, 11, 55, 3]
  • 3)、shuffle():对集合中的元素随机排列(打乱顺序)。主要有两种重载形式:
    • Ⅰ、void shuffle(List<?> list):使用默认的随机性(通过内部创建一个 Random 对象来实现)对指定集合的元素进行随机重新排序。
      // 1)、shuffle(List<?> list):使用默认的随机性对指定集合的元素进行随机重新排序。
      List<Integer> list = Arrays.asList(3, 55, 11, 4, 99);
      System.out.println("随机前:" + list); // [3, 55, 11, 4, 99]
      Collections.shuffle(list);
      System.out.println("默认随机后:" + list); // [99, 4, 55, 3, 11]
    • Ⅱ、void shuffle(List<?> list, Random rnd):使用指定的随机性(即传入的 Random 对象)对指定集合的元素进行随机重新排序。这允许开发者控制随机性的来源,以便在需要时重现相同的随机序列。
      // 2)、void shuffle(List<?> list, Random rnd):使用指定的随机性对集合的元素进行随机重新排序。
      List<Integer> list2 = Arrays.asList(3, 55, 11, 4, 99);
      Collections.shuffle(list2, new Random(10));
      System.out.println("指定随机后:" + list2); // [99, 11, 3, 55, 4]
      List<Integer> list3 = Arrays.asList(3, 55, 11, 4, 99);
      Collections.shuffle(list3, new Random(10)); // 重现与list2相同的随机序列
      System.out.println("指定随机后:" + list3);// [99, 11, 3, 55, 4]
  • 4)、void swap(List<?> list, int i, int j):将集合中索引为 i 和 j 位置的元素交换位置。
    // void swap(List<?> list, int i, int j):将i和j位置的元素交换位置。
    List<Integer> list = Arrays.asList(3, 55, 11, 4, 99);
    System.out.println("交换之前:" + list); // [3, 55, 11, 4, 99]
    Collections.swap(list, 1, 4);
    System.out.println("交换之后:" + list); // [3, 99, 11, 4, 55]

2、查找操作:主要有binarySearch()、max()、min()、frequency()等方法。

  • 1)、binarySearch():使用二分查找法已排序的集合中查找指定元素的位置。主要有两种重载形式:
    • Ⅰ、int binarySearch(List<? extends Comparable<? super T>> list, T key):基于自然排序的方式查找,即集合中的元素必须实现Comparable接口,返回查找的元素的索引,如果不存在则返回-1。
      // 1、binarySearch(list, key):基于自然排序的方式查找,返回查找的元素的索引,如果不存在则返回-1
      // 1)、Java内置类的集合进行查找
      List<Integer> list = Arrays.asList(3, 555, 777, 4, 99);
      System.out.println("排序前查找:");
      System.out.println(Collections.binarySearch(list, 3)); // 输出0
      System.out.println(Collections.binarySearch(list, 4)); // 输出-2,因为没有先对list进行排序
      Collections.sort(list);
      System.out.println("排序后查找:");
      System.out.println(Collections.binarySearch(list, 3)); // 输出0
      System.out.println(Collections.binarySearch(list, 4)); // 输出1
      System.out.println(Collections.binarySearch(list, 1)); // 输出-1,元素不存在
      // 2)、对象集合进行查找:集合中元素对应的类必须实现Comparable自然排序接口
      List<Student> students = new ArrayList<>(Arrays.asList(
              new Student("张三", 24), // PS:Student类实现了Comparable接口实现按年龄升序排序
              new Student("李四", 14),
              new Student("王五", 34)
      ));
      int index1 = Collections.binarySearch(students, new Student("张三", 24));
      System.out.println("排序前查找:" + index1); // -3,因为没有先对students进行排序
      Collections.sort(students); // 根据年龄字段进行排序
      int index2 = Collections.binarySearch(students, new Student("张三", 24));
      System.out.println("排序后查找:" + index2); // 输出1
    • Ⅱ、int binarySearch(List<? extends T> list, T key, Comparator<? super T> c):基于自定义排序的方式查找,需要在第三个参数中传入一个自定义比较器Comparator,返回查找的元素的索引,如果不存在则返回-1。
      // 2、binarySearch(list, key, c)基于自定义排序的方式查找
      // 需要在第三个参数中传入一个自定义比较器Comparator,返回查找的元素的索引,如果不存在则返回-1。
      List<Integer> list = Arrays.asList(3, 555, 777, 4, 99);
      Collections.sort(list); // 同样需要先对list进行排序
      System.out.println("查找元素:");
      Comparator<Integer> comparator = (o1, o2) -> o1 - o2;
      System.out.println(Collections.binarySearch(list, 3, comparator)); // 输出0
      System.out.println(Collections.binarySearch(list, 4, comparator)); // 输出1
      System.out.println(Collections.binarySearch(list, 1, comparator)); // 输出-1,因为元素不存在
      // 2)、对象集合进行查找:第三个参数传入了比较器,所以Person类不需要实现Comparator接口
      List<Person> people = new ArrayList<>(Arrays.asList(
          new Person("张三", 24),
          new Person("李四", 14),
          new Person("王五", 34)
      ));
      Collections.sort(people, Comparator.comparingInt(Person::getAge)); // 根据年龄进行进行升序排序
      System.out.println("根据年龄进行查找:");
      int index1 = Collections.binarySearch(people, new Person("张三", 24), Comparator.comparing(Person::getAge));
      System.out.println(index1); // 输出1
      int index2 = Collections.binarySearch(people, new Person("李四", 14), Comparator.comparing(Person::getAge));
      System.out.println(index2); // 输出0
      int index3 = Collections.binarySearch(people, new Person("李四", 33), Comparator.comparing(Person::getAge));
      System.out.println(index3); // 输出-3,负数就表示元素不存在(根据年龄33)
  • 2)、max()/min():查找集合中最大/最小的元素,主要有两种重载形式:
    • Ⅰ、<T extends Object & Comparable<? super T>> T max/min(Collection<? extends T> coll):基于自然排序的方式查找,即集合中的元素必须实现Comparable接口,使用元素的自然顺序来找出最大/最小元素。
      // 1)、max/min(Collection<? extends T> coll):基于自然排序的方式查找
      List<Integer> list = Arrays.asList(3, 555, 777, 4, 99);
      Integer max = Collections.max(list);
      Integer min = Collections.min(list);
      System.out.println("集合中元素的最大值为:" + max); // 输出777
      System.out.println("集合中元素的最小值为:" + min); // 输出3
    • Ⅱ、<T> T max(Collection<? extends T> coll, Comparator<? super T> comp):基于自定义排序的方式查找,需要在第二个参数中传入一个自定义比较器Comparator,使用指定的比较器来找出最大/最小元素。
      // 2)、max(Collection<? extends T> coll, Comparator<? super T> comp):基于自定义排序的方式查找,
      List<Person> people = new ArrayList<>(Arrays.asList(
          new Person("张三", 24),
          new Person("李四", 14),
          new Person("王五", 34)
      ));
      Person maxPerson = Collections.max(people, Comparator.comparingInt(Person::getAge));
      Person minPerson = Collections.min(people, Comparator.comparingInt(Person::getAge));
      System.out.println("年龄最大的为:" + maxPerson); // 输出Person{name='王五', age=34}
      System.out.println("年龄最小的为:" + minPerson); // 输出Person{name='李四', age=14}
  • 3)、int frequency(Collection<?> c, Object o):返回指定元素在集合中出现的次数。如果是对象集合则根据对象的equals()进行匹配。
    // 4、frequency(Collection<?> c, Object o):返回指定元素在集合中出现的次数。
    List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 2, 3, 4, 2));
    int frequency = Collections.frequency(list, 2);
    System.out.println("元素2出现的次数: " + frequency); // 输出3
    System.out.println("元素5出现的次数: " + Collections.frequency(list, 5)); // 输出0
    Person p1 = new Person("张三", 24);
    Person p2 = new Person("李四", 14);
    Person p3 = new Person("王五", 34);
    List<Person> people = Arrays.asList(p1, p2, p3);
    System.out.println(Collections.frequency(people, new Person("张三", 24))); // 输出0
    System.out.println(Collections.frequency(people, p1)); // 输出1,根据的是equals()来进行匹配

3、填充操作fill():用指定元素替换列表中的所有元素。

// 1、void fill(List<? super T> list, T obj)→ 用指定元素替换列表中的所有元素。
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Collections.fill(list, 0);
System.out.println("将集合中所有的元素都替换为0:" + list); // [0, 0, 0, 0, 0]

4、替换操作:boolean replaceAll(List<T> list, T oldVal, T newVal) → 将集合中指定元素全部替换成新的值。

// 1、boolean replaceAll(List<T> list, T oldVal, T newVal): 将集合中指定元素全部替换成新的值。
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 2, 3, 4, 2));
System.out.println("替换前:" + list); // [1, 2, 2, 3, 4, 2]
Collections.replaceAll(list, 2, 9);
System.out.println("替换后:" + list); // [1, 9, 9, 3, 4, 9]
Person p1 = new Person("张三", 24);
Person p2 = new Person("李四", 14);
Person p3 = new Person("王五", 34);
List<Person> people = new ArrayList<>(Arrays.asList(p1, p2, p3));
System.out.println(people); // [Person{name='张三', age=24}, Person{name='李四', age=14}, Person{name='王五', age=34}]
Collections.replaceAll(people, p1, new Person("张三", 25));
System.out.println(people); // [Person{name='张三', age=25}, Person{name='李四', age=14}, Person{name='王五', age=34}]

5、判断操作:boolean disjoint(Collection<?> c1, Collection<?> c2) → 判断两个集合是否没有任何共同元素,返回一个boolean值。

// 1、boolean disjoint(集合1, 集合2):判断两个集合是否没有任何共同元素,是则返回true,否则返回false。
List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3));
List<Integer> list2 = new ArrayList<>(Arrays.asList(4, 5, 6));
List<Integer> list3 = new ArrayList<>(Arrays.asList(1, 3, 5));
System.out.println("list1和list2是否没有任何共同元素:" + Collections.disjoint(list1, list2)); // true
System.out.println("list1和list3是否没有任何共同元素:" + Collections.disjoint(list1, list3)); // false
System.out.println("list2和list2是否没有任何共同元素:" + Collections.disjoint(list2, list3)); // false

6、不可变集合:Collections类提供了多种创建不可变的集合的方法,对不可变集合执行增删改操作时就会报错。不可变集合是线程安全、能够保证数据不变性以及在某些情况下提高性能(因为不可变对象可以被安全地缓存和共享)。

  • 1)、使用场景:
    • Ⅰ、多线程环境:在多线程环境中,不可变集合是线程安全的。多个线程可以同时访问和读取不可变集合,无需额外的同步机制。这样可以提高并发性能,并减少线程竞争和数据不一致性的问题。
    • Ⅱ、缓存:用来存储缓存的数据,可以避免在缓存中发生数据修改和同步的问题,从而提高缓存的性能和可靠性。
    • Ⅲ、方法返回值:作为方法的返回值,确保方法调用者无法修改返回的集合。提搞了安全性和稳定性,避免在方法调用过程中数据被意外修改。
    • Ⅳ、数据保护:用于存储需要保护数据完整性的数据,即使集合被其他代码引用也无法修改其中的元素。例如配置信息、常量数据等。
    • Ⅴ、函数式编程:使用不可变集合可以更容易地实现纯函数(即没有副作用的函数),从而提高代码的可读性和可维护性。
    • Ⅵ、防御式编程:在编程中,有时候可能无法完全控制外部对内部数据的访问和修改。使用不可变集合可以防止外部代码意外地修改内部数据,从而提高代码的健壮性和稳定性。
  • 2)、注意事项:
    • Ⅰ、任何尝试修改不可变集合的操作都会抛出 UnsupportedOperationException 异常。
    • Ⅱ、原始集合修改了会影响到不可变集合。
  • 3)、常用的不可变集合:主要有emptyXxx()、singletoXxx()、unmodifiableXxx()三个系列。
    • Ⅰ、emptyXxx():创建一个空的不可变集合。主要的方法有以下:
      • ①、final <T> List<T> emptyList():创建一个空的、不可变的List集合。
      • ②、final <T> Set<T> emptySet():创建一个空的、不可变的的Set集合。
      • ③、<E> SortedSet<E> emptySortedSet():创建一个空的、不可变的SortedSet集合。
      • ④、final <K,V> Map<K,V> emptyMap():创建一个空的、不可变的Map集合。
      • ⑤、final <K,V> SortedMap<K,V> emptySortedMap() :创建一个空的、不可变的SortedMap集合。
        // 1、emptyXxx()系列:空的不可变集合
        List<String> emptyList = Collections.emptyList();
        System.out.println(emptyList); // 输出 []
        Set<String> emptySet = Collections.emptySet();
        System.out.println(emptySet); // 输出 []
        SortedSet<String> emptySortedSet = Collections.emptySortedSet();
        System.out.println(emptySortedSet); // 输出 []
        Map<String, Integer> emptyMap = Collections.emptyMap();
        System.out.println(emptyMap); // 输出 {}
        SortedMap<String, Integer> emptySortedMap = Collections.emptySortedMap();
        System.out.println(emptySortedMap); // 输出 {}
    • Ⅱ、singletoXxx():创建一个只有一个元素的不可变集合。主要的方法有以下:
      • ①、<T> List<T> singletonList(T o):创建一个只包含一个元素、不可变的List集合。
      • ②、<T> Set<T> singleton(T o):创建一个只包含一个元素、不可变的Set集合。
      • ③、<K,V> Map<K,V> singletonMap(K key, V value):创建一个只包含一个键值对、不可变的Map集合。
        // 2、singletoXxx()系列:只有一个元素的不可变集合
        List<String> singletonList = Collections.singletonList("张三");
        System.out.println(singletonList); // 输出 [张三]
        Set<String> singletonSet = Collections.singleton("李四");
        System.out.println(singletonSet); // 输出 [李四]
        Map<String, Integer> singletonMap = Collections.singletonMap("张三", 23);
        System.out.println(singletonMap); // 输出 {张三=23}
    • Ⅲ、unmodifiableXxx():为指定集合创建一个不可变集合。主要的方法有以下:
      • ①、<T> List<T> singletonList(T o):创建一个只包含一个元素、不可变的List集合。
      • ②、<T> Set<T> singleton(T o):创建一个只包含一个元素、不可变的Set集合。
      • ③、<K,V> Map<K,V> singletonMap(K key, V value):创建一个只包含一个键值对、不可变的Map集合。
        // 3、unmodifiableXxx()系列:为指定集合创建一个不可变集合
        List<String> list = new ArrayList<>(Arrays.asList("zhangsan", "lisi", "wangwu"));
        List<String> unmodifiableList = Collections.unmodifiableList(list);
        System.out.println(unmodifiableList); // 输出 [zhangsan, lisi, wangwu]
        HashSet<String> set = new HashSet<>(list);
        Set<String> unmodifiableSet = Collections.unmodifiableSet(set);
        System.out.println(unmodifiableSet); // 输出 [lisi, zhangsan, wangwu]
        TreeSet<String> treeSet = new TreeSet<>(set);
        SortedSet<String> unmodifiableSortedSet = Collections.unmodifiableSortedSet(treeSet);
        System.out.println(unmodifiableSortedSet); // 输出 [lisi, wangwu, zhangsan]
        Map<String, Integer> map = new HashMap<>();
        map.put("张三", 25);
        Map<String, Integer> unmodifiableMap = Collections.unmodifiableMap(map);
        System.out.println(unmodifiableMap); // 输出 {张三=25}
        TreeMap<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("李四", 35);
        SortedMap<String, Integer> unmodifiableSortedMap = Collections.unmodifiableSortedMap(treeMap);
        System.out.println(unmodifiableSortedMap); // 输出 {李四=35}

7、同步控制集合:Collections类提供了多种同步控制集合的方法,同步控制集合是线程安全的,在多线程环境下可以安全地访问和修改集合。主要为synchronizedXXX()系列的方法:

  • 1)、<T> Collection<T> synchronizedCollection(Collection<T> c):根据指定集合创建一个同步的Collection集合。
  • 2)、<T> List<T> synchronizedList(List<T> list):根据指定List创建一个同步的List集合。
  • 3)、<T> Set<T> synchronizedSet(Set<T> s):根据指定Set创建一个同步的Set集合。
  • 4)、<T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s):根据指定SortedSet创建一个同步的SortedSet集合。
  • 5)、<K,V> Map<K,V> synchronizedMap(Map<K,V> m):根据指定Map创建一个同步的Map集合。
  • 6)、<K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m):根据指定SortedMap创建一个同步的SortedMap集合。
// 同步控制集合
// 1、创建同步控制集合
Collection<Object> synchronizedCollection = Collections.synchronizedCollection(new ArrayList<>());
System.out.println(synchronizedCollection); // 输出 []
List<Object> synchronizedList = Collections.synchronizedList(new ArrayList<>());
System.out.println(synchronizedList); // 输出 []
Set<Object> synchronizedSet = Collections.synchronizedSet(new HashSet<>());
System.out.println(synchronizedSet); // 输出 []
SortedSet<Object> synchronizedSortedSet = Collections.synchronizedSortedSet(new TreeSet<>());
System.out.println(synchronizedSortedSet); // 输出 []
Map<String, Integer> synchronizedMap = Collections.synchronizedMap(new HashMap<>());
System.out.println(synchronizedMap); // 输出 {}
SortedMap<String, Integer> synchronizedSortedMap = Collections.synchronizedSortedMap(new TreeMap<>());
System.out.println(synchronizedSortedMap); // 输出 {}
// 2、迭代同步控制集合
List<Integer> list = new ArrayList<>(Arrays.asList(1, 44, 33, 22, 677));
List<Integer> synchronizedList1 = Collections.synchronizedList(list);
synchronized (synchronizedList1) {
    for (Integer integer : synchronizedList1) {
        System.out.println(integer); // 输出每一个元素
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值