Java Collections 类中方法详解

java.util.Collections 类

java.util.Collections 类是 Java 集合框架的一个工具类,它包含一系列静态方法,用于操作和处理各种类型的集合。 这些方法提供了对集合进行排序、查找、同步控制、创建只读集合等常见操作的便捷方式。 注意: Collections 类本身不能被实例化,它的所有方法都是静态的,可以直接通过类名调用。

一、 排序 (Sorting)

  1. sort(List<T> list)

    • 作用: 对指定的 List 集合进行升序排序。

    • 要求: 列表中的元素必须实现 Comparable 接口,即具有自然顺序。 否则会抛出 ClassCastException

    • 算法: 通常使用归并排序 (Merge Sort) 或 TimSort (一种混合排序算法,结合了归并排序和插入排序的优点),具有较好的平均性能和最坏情况性能。

    • 示例:

      List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 2, 8, 1, 9));
      Collections.sort(numbers);
      System.out.println(numbers); // 输出:[1, 2, 5, 8, 9]
      
  2. sort(List<T> list, Comparator<? super T> c)

    • 作用: 根据指定的比较器 (Comparator) 对 List 集合进行排序。

    • 要求: 列表中的元素不需要实现 Comparable 接口,可以使用自定义的比较器来定义排序规则。

    • 算法: 同样通常使用归并排序或 TimSort。

    • 示例:

      List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie", "David"));
      Collections.sort(names, (s1, s2) -> s1.length() - s2.length()); // 根据字符串长度排序
      System.out.println(names); // 输出:[Bob, Alice, David, Charlie]
      

二、 查找 (Searching)

  1. binarySearch(List<? extends Comparable<? super T>> list, T key)

    • 作用: 使用二分查找算法在指定的 List 集合中查找指定的元素。

    • 要求:

      • 列表必须已排序(升序),否则结果不确定。
      • 列表中的元素必须实现 Comparable 接口,即具有自然顺序。
    • 返回值:

      • 如果找到元素,则返回元素的索引。
      • 如果没有找到元素,则返回 (-(insertion point) - 1),其中 insertion point 是将元素插入到列表中以保持排序顺序的索引。
    • 示例:

      List<Integer> numbers = Arrays.asList(1, 2, 5, 8, 9); // 必须已排序
      int index = Collections.binarySearch(numbers, 5);
      System.out.println("Index of 5: " + index); // 输出:Index of 5: 2
      
      int notFound = Collections.binarySearch(numbers, 6);
      System.out.println("Index of 6: " + notFound); // 输出:Index of 6: -4
      
  2. binarySearch(List<? extends T> list, T key, Comparator<? super T> c)

    • 作用: 使用二分查找算法在指定的 List 集合中查找指定的元素,使用指定的比较器进行比较。

    • 要求: 列表必须已排序(按照比较器的规则),否则结果不确定。

    • 返回值:binarySearch(List<? extends Comparable<? super T>> list, T key) 相同。

    • 示例:

      List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David"); // 必须按照比较器的规则排序
      Collections.sort(names, (s1, s2) -> s1.length() - s2.length()); // 先按长度排序
      int index = Collections.binarySearch(names, "David", (s1, s2) -> s1.length() - s2.length());
      System.out.println("Index of David: " + index); // 输出:Index of David: 2
      

三、 最大值和最小值 (Maximum and Minimum)

  1. max(Collection<? extends T> coll)

    • 作用: 返回指定集合中的最大元素。

    • 要求: 集合中的元素必须实现 Comparable 接口,即具有自然顺序。

    • 示例:

      List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9);
      int max = Collections.max(numbers);
      System.out.println("Max: " + max); // 输出:Max: 9
      
  2. min(Collection<? extends T> coll)

    • 作用: 返回指定集合中的最小元素。

    • 要求: 集合中的元素必须实现 Comparable 接口,即具有自然顺序。

    • 示例:

      List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9);
      int min = Collections.min(numbers);
      System.out.println("Min: " + min); // 输出:Min: 1
      
  3. max(Collection<? extends T> coll, Comparator<? super T> comp)

    • 作用: 返回指定集合中的最大元素,使用指定的比较器进行比较。

    • 要求: 不需要实现 Comparable接口。

    • 示例:

      List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
      String longestName = Collections.max(names, (s1, s2) -> s1.length() - s2.length());
      System.out.println("Longest name: " + longestName); // 输出:Longest name: Charlie
      
  4. min(Collection<? extends T> coll, Comparator<? super T> comp)

    • 作用: 返回指定集合中的最小元素,使用指定的比较器进行比较。

    • 要求: 不需要实现 Comparable接口。

    • 示例:

      List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
      String shortestName = Collections.min(names, (s1, s2) -> s1.length() - s2.length());
      System.out.println("Shortest name: " + shortestName); // 输出:Shortest name: Bob
      

四、 反转 (Reversing)

  1. reverse(List<?> list)

    • 作用: 反转指定 List 集合中元素的顺序。

    • 示例:

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

五、 随机排序 (Shuffling)

  1. shuffle(List<?> list)

    • 作用: 使用默认随机源随机排列指定的 List 集合。

    • 示例:

      List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
      Collections.shuffle(numbers);
      System.out.println(numbers); // 输出:[随机排列后的结果,例如:[3, 1, 5, 2, 4]]
      
  2. shuffle(List<?> list, Random rnd)

    • 作用: 使用指定的随机源随机排列指定的 List 集合。

    • 示例:

      List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
      Random random = new Random();
      Collections.shuffle(numbers, random);
      System.out.println(numbers); // 输出:[随机排列后的结果,例如:[2, 5, 1, 4, 3]]
      

六、 填充 (Filling)

  1. fill(List<? super T> list, T obj)

    • 作用: 使用指定的对象替换指定 List 集合中的所有元素。

    • 示例:

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

七、 复制 (Copying)

  1. copy(List<? super T> dest, List<? extends T> src)

    • 作用: 将所有元素从源 List 集合复制到目标 List 集合。

    • 要求:

      • 目标列表的长度必须大于或等于源列表的长度,否则会抛出 IndexOutOfBoundsException
      • 目标列表和源列表的元素类型必须兼容。
    • 示例:

      List<Integer> source = Arrays.asList(1, 2, 3, 4, 5);
      List<Integer> destination = new ArrayList<>(Arrays.asList(0, 0, 0, 0, 0)); // 长度必须 >= source.size()
      Collections.copy(destination, source);
      System.out.println(destination); // 输出:[1, 2, 3, 4, 5]
      

八、 交换 (Swapping)

  1. swap(List<?> list, int i, int j)
    作用: 在指定列表中交换指定位置的元素。
List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Collections.swap(numbers, 0, 4);
System.out.println(numbers); // 输出:[5, 2, 3, 4, 1]

九、 频率 (Frequency)

  1. frequency(Collection<?> c, Object o)
    作用: 返回集合中与指定对象相等的元素的数量。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Alice");
int frequency = Collections.frequency(names, "Alice");
System.out.println("Frequency of Alice: " + frequency); // 输出:Frequency of Alice: 2

十、 线程安全集合 (Synchronized Collections)

Collections 类提供了一组静态方法,用于将非线程安全的集合转换为线程安全的集合。 这些方法本质上是对集合的操作进行加锁,以实现线程安全。

  1. synchronizedCollection(Collection<T> c)

    • 作用: 返回一个线程安全的 Collection

    • 原理:Collection 接口中的所有方法进行同步。

    • 示例:

      Collection<Integer> numbers = new ArrayList<>();
      Collection<Integer> syncNumbers = Collections.synchronizedCollection(numbers); // 创建线程安全的 Collection
      
  2. synchronizedList(List<T> list)

    • 作用: 返回一个线程安全的 List

    • 原理:List 接口中的所有方法进行同步。

    • 示例:

      List<Integer> numbers = new ArrayList<>();
      List<Integer> syncNumbers = Collections.synchronizedList(numbers); // 创建线程安全的 List
      
  3. synchronizedSet(Set<T> s)

    • 作用: 返回一个线程安全的 Set

    • 原理:Set 接口中的所有方法进行同步。

    • 示例:

      Set<Integer> numbers = new HashSet<>();
      Set<Integer> syncNumbers = Collections.synchronizedSet(numbers); // 创建线程安全的 Set
      
  4. synchronizedMap(Map<K,V> m)

    • 作用: 返回一个线程安全的 Map

    • 原理:Map 接口中的所有方法进行同步。

    • 示例:

      Map<String, Integer> scores = new HashMap<>();
      Map<String, Integer> syncScores = Collections.synchronizedMap(scores); // 创建线程安全的 Map
      

注意事项:

  • 性能较低: synchronized 集合的性能较低,因为所有操作都需要获取锁。在高并发场景下,建议使用 java.util.concurrent 包提供的并发集合类(例如 ConcurrentHashMap, CopyOnWriteArrayList)。
  • 迭代: 即使使用了 synchronized 集合,在迭代集合时仍然需要进行同步,以避免 ConcurrentModificationException。 可以使用 synchronized 代码块或 synchronized 方法来保护迭代过程。

示例:线程安全的迭代

List<Integer> numbers = Collections.synchronizedList(new ArrayList<>());

synchronized (numbers) { // 同步代码块
    Iterator<Integer> iterator = numbers.iterator();
    while (iterator.hasNext()) {
        Integer number = iterator.next();
        // 处理 number
    }
}

十一、 不可修改的集合 (Unmodifiable Collections)

Collections 类提供了一组静态方法,用于创建不可修改的集合(只读集合)。 尝试修改这些集合会抛出 UnsupportedOperationException 异常。

  1. unmodifiableCollection(Collection<? extends T> c)

    • 作用: 返回一个不可修改的 Collection
  2. unmodifiableList(List<? extends T> list)

    • 作用: 返回一个不可修改的 List
  3. unmodifiableSet(Set<? extends T> s)

    • 作用: 返回一个不可修改的 Set
  4. unmodifiableSortedSet(SortedSet<T> s)

  • 作用: 返回一个不可修改的 SortedSet
  1. unmodifiableNavigableSet(NavigableSet<T> s)
  • 作用: 返回一个不可修改的 NavigableSet
  1. unmodifiableMap(Map<? extends K,? extends V> m)

    • 作用: 返回一个不可修改的 Map
  2. unmodifiableSortedMap(SortedMap<K, V> m)

  • 作用: 返回一个不可修改的 SortedMap
  1. unmodifiableNavigableMap(NavigableMap<K, V> m)
  • 作用: 返回一个不可修改的 NavigableMap

使用场景:

  • 保护集合数据: 防止外部代码修改集合中的数据。
  • 创建只读的配置对象: 例如,将应用程序的配置信息存储在一个 Map 中,并将其设置为不可修改的,以防止运行时被意外修改。

示例:

List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie"));
List<String> unmodifiableNames = Collections.unmodifiableList(names);

// 尝试修改 unmodifiableNames 会抛出 UnsupportedOperationException
try {
    unmodifiableNames.add("David"); // 抛出 UnsupportedOperationException
} catch (UnsupportedOperationException e) {
    System.out.println("Caught exception: " + e);
}

// 修改 names 会影响 unmodifiableNames (因为 unmodifiableNames 只是一个视图)
names.add("David");
System.out.println(unmodifiableNames); // 输出:[Alice, Bob, Charlie, David]

注意事项:

  • 只读视图: unmodifiable 方法返回的集合只是一个只读视图,它仍然引用原始集合。 如果原始集合发生了改变,那么只读视图也会反映这些改变。
  • 浅拷贝: unmodifiable 方法返回的只是集合的 浅拷贝
### 题目重述 本题要求定义一个 `Student` ,实现 `Comparable<Student>` 接口,并正确重写 `compareTo` 方法,以便可以使用 `Collections.sort()` 和 `Collections.binarySearch()` 对 `LinkedList<Student>` 进行排序和查找。 --- ### 详解 当前代码整体结构是正确的,但存在一些细节问题,可能导致运行结果不准确或不稳定。我们来逐步分析: #### ✅ 正确的部分: 1. `Student` 实现了 `Comparable<Student>` 接口。 2. `compareTo` 方法基于 `height` 属性进行比较,逻辑正确。 3. 使用了 `Collections.sort(list)` 进行排序。 4. 使用了 `Collections.binarySearch(list, st)` 进行查找。 5. 使用了 `Iterator` 遍历链表(虽然在代码中未显示完整遍历过程)。 #### ❗存在问题: 1. **未遍历输出排序后的列表** - 虽然声明了 `Iterator<Student> iterator = list.iterator();`,但没有实际的 `while` 循环进行输出。 2. **`binarySearch` 结果判断错误** - 当 `index >= 0` 时才是“找到”,但原判断为 `if(index > 0)`,这将导致当目标元素位于索引 0 时被误判为“不存在”。 3. **缺少必要的 `toString()` 方法** - 在 `Student` 中没有重写 `toString()`,因此打印对象时会输出似 `exam.Student@xxxx` 的内容,建议加上。 --- ### 修改建议如下: ```java // Student添加toString方法 @Override public String toString() { return "Student{name='" + name + "', height=" + height + "}"; } ``` ```java // 主方法中修改查找判断,并增加遍历输出 // 遍历输出排序后的学生 Iterator<Student> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } // 修改查找部分的判断 Student st = new Student(190, "lin"); int index = Collections.binarySearch(list, st); if (index >= 0) { // 修正为 >= 0 System.out.println("该生存在:" + list.get(index)); } else { System.out.println("不存在"); } ``` --- ### 知识点 1. **Comparable接口** - 实现该接口可让对象支持自然排序。 - 必须重写 `compareTo()` 方法。 2. **Collections.binarySearch** - 用于在有序集合中高效查找元素。 - 要求集合已排序,否则结果不确定。 3. **二分查找的前提条件** - 数据必须有序。 - 否则不能保证查找结果的准确性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值