当前位置:   article > 正文

【java】集合工具类Collections

【java】集合工具类Collections

Java集合框架中的Collections工具类是一个静态类,它提供了一系列的静态方法,用于操作各种集合,如List, Set, Map等。这些方法包括排序、搜索、替换、同步控制以及创建不可变集合等功能。以下是一些主要的方法:

以下是Collections.sort()方法的使用:

  1. 单一条件排序

    List<Integer> numbers = Arrays.asList(5, 2, 9, 1, 5);
    Collections.sort(numbers);
    
    • 1
    • 2

    这个例子中,Collections.sort()会按照元素的自然顺序(对于数值类型就是升序)对列表进行排序。

  2. 自定义比较器排序
    如果列表中的元素是自定义对象,并且没有实现Comparable接口,或者需要按照特定规则排序,你可以提供一个Comparator

    class Person {
        String name;
        int age;
    
        // 构造函数、getter和setter省略...
    }
    
    List<Person> people = ... // 初始化列表
    Collections.sort(people, new Comparator<Person>() {
        @Override
        public int compare(Person p1, Person p2) {
            return p1.getName().compareTo(p2.getName()); // 按姓名排序
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    或者使用Java 8的Lambda表达式简化代码:

    Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));
    
    • 1
  3. 多条件排序
    多条件排序通常通过自定义Comparator来实现,例如,先按一个属性排序,如果相等再按另一个属性排序:

    Collections.sort(people, new Comparator<Person>() {
        @Override
        public int compare(Person p1, Person p2) {
            int ageComparison = Integer.compare(p1.getAge(), p2.getAge());
            if (ageComparison != 0) {
                return ageComparison; // 先按年龄排序
            } else {
                return p1.getName().compareTo(p2.getName()); // 年龄相同则按姓名排序
            }
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  4. 反转排序
    如果你想反向排序,可以使用Collections.reverseOrder()方法创建一个反转比较器,然后传递给sort()方法:

    Collections.sort(numbers, Collections.reverseOrder()); // 数字降序排序
    Collections.sort(people, Collections.reverseOrder()); // 对象按照默认比较器降序排序
    
    • 1
    • 2
  5. 泛型限制
    Collections.sort()方法适用于任何实现了Comparable接口的类型,或者你提供了Comparator的类型。

请注意,Collections.sort()方法会改变原始列表的顺序。如果你不希望改变原列表,可以先复制一份再进行排序。

以下是主要的查找和替换方法:

  1. 查找方法

    • binarySearch(List<? extends Comparable<? super T>> list, T key):这个方法使用二分查找算法在已经排序的List中查找指定的元素。返回值是元素的位置,如果未找到则返回负数。

    示例:

    List<Integer> sortedNumbers = Arrays.asList(1, 3, 5, 7, 9);
    int index = Collections.binarySearch(sortedNumbers, 5);
    System.out.println(index); // 输出:2
    
    • 1
    • 2
    • 3
  2. 替换方法

    • replaceAll(List<?> list, T oldVal, T newVal):这个方法会遍历整个List,并将所有出现的oldVal替换为newVal

    示例:

    List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 2, 3, 4, 2));
    Collections.replaceAll(numbers, 2, 7);
    System.out.println(numbers); // 输出:[1, 7, 7, 3, 4, 7]
    
    • 1
    • 2
    • 3

请注意,binarySearch()方法要求List必须是有序的,而replaceAll()方法则可以应用于任何List,但不会返回替换的次数或是否进行了替换,它只是默默地完成替换操作。

如果你需要在未排序的列表中查找特定元素,通常需要自己遍历列表来实现。对于替换操作,replaceAll()方法是唯一的选择,因为它可以替换列表中所有匹配的元素。

以下是几个同步控制关键方法:

  1. synchronizedList(List list):这个方法返回一个线程安全的List视图,它的所有公共操作都是同步的。这意味着当多个线程尝试同时修改这个列表时,它们会按照一定的顺序进行,避免数据的不一致。

    示例:

    List<String> nonSyncList = new ArrayList<>();
    List<String> syncList = Collections.synchronizedList(nonSyncList);
    
    • 1
    • 2
  2. synchronizedSet(Set set):这个方法将给定的Set转换为线程安全的Set。类似地,所有对这个集合的操作都是线程安全的。

    示例:

    Set<String> nonSyncSet = new HashSet<>();
    Set<String> syncSet = Collections.synchronizedSet(nonSyncSet);
    
    • 1
    • 2
  3. synchronizedMap(Map<K, V> map):这个方法返回一个线程安全的Map视图,它的所有公共操作都是同步的。

    示例:

    Map<String, Integer> nonSyncMap = new HashMap<>();
    Map<String, Integer> syncMap = Collections.synchronizedMap(nonSyncMap);
    
    • 1
    • 2
  4. synchronizedSortedMap(SortedMap<K, V> m):这个方法将给定的SortedMap转换为线程安全的SortedMap

    示例:

    SortedMap<String, Integer> nonSyncSortedMap = new TreeMap<>();
    SortedMap<String, Integer> syncSortedMap = Collections.synchronizedSortedMap(nonSyncSortedMap);
    
    • 1
    • 2

虽然这些同步集合提供了基本的线程安全性,但请注意,它们并不是完全线程安全的。例如,迭代器的创建不是线程安全的,因此在迭代过程中添加或删除元素仍需要外部同步。另外,只对整个集合进行同步,而不是对单个元素,所以如果需要更细粒度的控制,可能需要使用java.util.concurrent包中的线程安全集合或显式同步代码块。

以下是一些常见的集合转换方法:

  1. 数组转换为列表
    使用Arrays.asList()方法可以将数组转换为ArrayList。这个方法不适用于基本类型的数组,只能用于对象数组。对于基本类型,需要使用Arrays.stream()collect()方法配合Java 8的流API。

    对象数组转换示例:

    String[] stringArray = {"A", "B", "C"};
    List<String> stringList = Arrays.asList(stringArray);
    
    • 1
    • 2

    基本类型数组转换示例(使用Java 8及以上版本):

    int[] intArray = {1, 2, 3};
    List<Integer> intList = IntStream.of(intArray).boxed().collect(Collectors.toList());
    
    • 1
    • 2
  2. 列表转换为数组
    要将List转换回数组,可以使用ListtoArray()方法,通常需要传入一个预先创建的数组,因为toArray()方法不知道应该创建多大的数组。

    示例:

    List<String> stringList = ... // 初始化列表
    String[] stringArray = new String[stringList.size()];
    stringArray = stringList.toArray(stringArray);
    
    • 1
    • 2
    • 3

如果你需要在不同类型的集合之间转换,比如从ListSet,或者从ListQueue,通常需要使用集合的构造函数或者Copy Constructor。例如:

List<String> myList = ... // 初始化列表
Set<String> mySet = new HashSet<>(myList);

// 或者
List<String> myList = ... // 初始化列表
Queue<String> myQueue = new LinkedList<>(myList);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在转换时,确保目标集合的类型与源集合中的元素兼容,否则可能会抛出ClassCastException。如果需要更复杂的转换,例如,将集合转换为特定类型的集合,可能需要使用流API或其他库,如Apache Commons Collections或Guava。

使用Collections工具类可以极大地简化集合操作,提高代码的可读性和效率。请注意,对于不是线程安全的集合,如果在多线程环境下使用Collections的同步控制方法,可以确保操作的安全性。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/499762
推荐阅读
相关标签
  

闽ICP备14008679号