Java 集合:Collections 工具类

Java 的 Collections(java.util.Collections)类是一个工具类,包含了大量用于在 Java 中处理集合的实用静态方法。在本教程中,我将介绍其中一些最有用的方法。

addAll() 添加数量可变的元素

addAll() 方法可以向集合(通常是 List 或 Set)中添加数量可变的元素。下面是一个调用集合 addAll() 方法的 Java 代码示例:

package com.hxstrive.java_collection;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class CollectionsAddAllDemo {
    public static void main(String[] args) {
        // 创建泛型为String的ArrayList
        List<String> list = new ArrayList<>();
        
        // 使用Collections.addAll()批量添加元素
        boolean allAdded = Collections.addAll(list,
                "element 1", "element 2", "element 3", "element 4", "element 5");
        
        // 输出添加结果
        System.out.println("所有元素是否添加成功: " + allAdded);
        System.out.println("列表中的元素:");
        for (String element : list) {
            System.out.println("- " + element);
        }
        
        // 演示继续添加更多元素
        Collections.addAll(list, "element 6", "element 7");
        System.out.println("\n添加更多元素后的列表:");
        System.out.println(list);
        
        // 演示添加不同类型元素会编译报错
        // Collections.addAll(list, 123); // 错误: 不兼容的类型,int无法转换为String
    }
}

运行结果:

所有元素是否添加成功: true
列表中的元素:
- element 1
- element 2
- element 3
- element 4
- element 5

添加更多元素后的列表:
[element 1, element 2, element 3, element 4, element 5, element 6, element 7]

  

binarySearch() 二分查找元素

binarySearch() 方法可以使用二分查找算法在 List 中搜索元素。在使用 binarySearch() 搜索之前,必须以升序对 List 进行排序。

二分查找算法(Binary Search Algorithm),也称为 “折半查找”,是一种高效的有序数据查找算法。其核心思想是通过不断将 “查找范围减半”,快速缩小目标元素的可能位置,最终定位到目标(或确定目标不存在),适用于已排序的线性数据结构(如数组、有序列表)。

下面是一个使用 binarySearch() 方法搜索 List 的示例:

package com.hxstrive.java_collection;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class StringListBinarySearch {
    public static void main(String[] args) {
        // 创建字符串列表并添加元素
        List<String> list = new ArrayList<>();
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        list.add("five");
        
        // 打印排序前的列表
        System.out.println("排序前的列表: " + list);
        
        // 对列表进行排序(按字符串自然顺序)
        Collections.sort(list);
        System.out.println("排序后的列表: " + list);
        
        // 使用二分查找寻找"four"
        int index = Collections.binarySearch(list, "four");
        // 输出查找结果
        System.out.println("元素\"four\"的索引位置: " + index);
    }
}

运行结果:

排序前的列表: [one, two, three, four, five]
排序后的列表: [five, four, one, three, two]
元素"four"的索引位置: 1

  

copy() 复制集合

copy() 方法可以将 List 中的所有元素复制到另一个 List 中。例如:

package com.hxstrive.java_collection;

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class CollectionsCopyDemo {
    public static void main(String[] args) {
        List<String> source = new ArrayList<>(Arrays.asList("a", "b", "c"));
        List<String> dest = new ArrayList<>();

        // 关键:先填充足够的空元素,确保目标列表容量 >= 源列表
        for (int i = 0; i < source.size(); i++) {
            dest.add(null); // 填充null作为占位
        }

        Collections.copy(dest, source); // 此时可正常复制
        System.out.println(dest); // 输出 [a, b, c]
    }
}

Collections.copy() 要求目标列表容量必须 >= 源列表,否则抛出 Source does not fit in dest 异常:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in dest
	at java.util.Collections.copy(Collections.java:556)

copy() 方法适合覆盖已有元素的场景,不适合动态创建副本。日常开发中,使用 new ArrayList<>(source) 或 addAll() 是更简单安全的列表复制方式。


reverse() 反转列表

Collections reverse() 方法可以反转 List 中的元素。下面是一个反转 List 元素的示例:

package com.hxstrive.java_collection;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class CollectionsReverseDemo {
    public static void main(String[] args) {
        // 创建字符串列表并添加元素
        List<String> list = new ArrayList<String>();
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        
        // 打印反转前的列表
        System.out.println("反转前的列表: " + list);
        // 调用reverse()方法反转列表元素顺序
        Collections.reverse(list);
        // 打印反转后的列表
        System.out.println("反转后的列表: " + list);
    }
}

运行结果:

反转前的列表: [one, two, three, four]
反转后的列表: [four, three, two, one]

  

shuffle() 随机重排序

Collections shuffle() 方法可以对列表中的元素进行洗牌。“洗牌”指将列表中的元素随机重新排列,就像洗牌时将扑克牌打乱顺序一样。例如:

package com.hxstrive.java_collection;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class CollectionsShuffleDemo {
    public static void main(String[] args) {
        // 创建字符串列表并添加元素
        List<String> list = new ArrayList<String>();
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        list.add("five");
        System.out.println("洗牌前的列表: " + list);
        
        // 第一次随机洗牌(使用默认随机数生成器)
        Collections.shuffle(list);
        System.out.println("第一次洗牌后: " + list);
        
        // 第二次随机洗牌(结果通常不同)
        Collections.shuffle(list);
        System.out.println("第二次洗牌后: " + list);
        
        // 使用指定种子的Random对象进行洗牌
        Random fixedRandom = new Random(100); // 固定种子
        Collections.shuffle(list, fixedRandom);
        System.out.println("指定种子洗牌后: " + list);
    }
}

运行结果:

洗牌前的列表: [one, two, three, four, five]
第一次洗牌后: [three, four, one, five, two]
第二次洗牌后: [three, two, five, four, one]
指定种子洗牌后: [one, four, two, five, three]

  

sort() 排序

sort() 方法可以对 List 进行排序。例如:示例:

package com.hxstrive.java_collection;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class CollectionSortDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        System.out.println("排序前的列表: " + list);
        
        // 使用Collections.sort()进行自然排序
        Collections.sort(list);
        System.out.println("排序后的列表: " + list);
    }
}

运行结果:

排序前的列表: [one, two, three, four]
排序后的列表: [four, one, three, two]

  

min() 返回最小值

min() 方法可以根据元素的自然排序找到 List 中的最小元素。例如:

package com.hxstrive.java_collection;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class CollectionsMinDemo {
    public static void main(String[] args) {
        List source = new ArrayList();
        source.add("1");
        source.add("2");
        source.add("3");
        source.add("0");
        // 使用Collections.min()获取最小元素(需要强制类型转换,因为列表未使用泛型)
        String min = (String) Collections.min(source);
        System.out.println("列表中的元素: " + source);
        System.out.println("列表中的最小元素: " + min);
        
        // 演示使用泛型的更安全方式
        List<String> genericList = new ArrayList<>();
        genericList.add("apple");
        genericList.add("banana");
        genericList.add("cherry");
        String minStr = Collections.min(genericList);
        System.out.println("\n泛型列表中的元素: " + genericList);
        System.out.println("泛型列表中的最小元素: " + minStr);
    }
}

运行结果:

列表中的元素: [1, 2, 3, 0]
列表中的最小元素: 0

泛型列表中的元素: [apple, banana, cherry]
泛型列表中的最小元素: apple

注意,Collections.min(source) 方法用于获取列表中的最小元素,其比较基于元素的自然顺序(实现 Comparable 接口)。由于示例中的源列表 source 未使用泛型,返回的是 Object 类型,因此需要强制转换为 String。对于字符串元素,最小元素的判断基于字典顺序(Unicode 值比较):

  • 数字字符串比较:"0" < "1" < "2" < "3"

  • 字母字符串比较:"apple" < "banana" < "cherry"(基于首字母的 Unicode 值)

推荐使用泛型列表(如 List<String>),可以避免强制类型转换,使代码更安全简洁。

  

max() 返回最大值

max() 方法可以根据元素的自然顺序找出 List 中的最大元素。例如:

package com.hxstrive.java_collection;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class CollectionsMaxDemo {
    public static void main(String[] args) {
        List source = new ArrayList();
        source.add("1");
        source.add("2");
        source.add("3");
        source.add("5");
        source.add("4");
        // 使用Collections.max()获取最大元素(需强制类型转换,因列表未使用泛型)
        String max = (String) Collections.max(source);
        System.out.println("列表中的元素: " + source);
        System.out.println("列表中的最大元素: " + max);
        
        // 演示泛型列表的用法(更安全,无需类型转换)
        List<String> fruitList = new ArrayList<>();
        fruitList.add("orange");
        fruitList.add("apple");
        fruitList.add("watermelon");
        String maxFruit = Collections.max(fruitList);
        System.out.println("\n水果列表中的元素: " + fruitList);
        System.out.println("水果列表中的最大元素: " + maxFruit);
    }
}

运行结果:

列表中的元素: [1, 2, 3, 5, 4]
列表中的最大元素: 5

水果列表中的元素: [orange, apple, watermelon]
水果列表中的最大元素: watermelon

注意,Collections.max() 方法通过遍历列表比较所有元素,找出自然顺序中最大的元素,适用于所有元素可比较的列表。

  

replaceAll() 替换所有

replaceAll() 方法可以用另一个元素替换一个元素的所有出现。您可以将要替换的元素和要替换的元素作为参数传递给 replaceAll() 方法。如果有元素被替换,Collections replaceAll() 方法返回 true;如果没有,则返回 false。例如:

package com.hxstrive.java_collection;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class ReplaceAllExample {
    public static void main(String[] args) {
        List source = new ArrayList();
        source.add("A");
        source.add("B");
        source.add("A");
        
        // 使用Collections.replaceAll()替换元素
        boolean replacedAny = Collections.replaceAll(source, "A", "C");
        System.out.println("是否有元素被替换: " + replacedAny);
        System.out.println("替换后的列表: " + source);
        
        // 演示替换不存在的元素
        boolean replacedNone = Collections.replaceAll(source, "X", "Y");
        System.out.println("\n替换不存在的元素时是否有替换: " + replacedNone);
        System.out.println("替换不存在元素后的列表: " + source);
    }
}

运行结果:

是否有元素被替换: true
替换后的列表: [C, B, C]

替换不存在的元素时是否有替换: false
替换不存在元素后的列表: [C, B, C]

执行此示例后,源 List 将包含元素 C、B 和 C。由于 List 中至少有一个元素被替换,因此 replacedAny 变量的值为 true。

Collections replaceAll() 方法使用每个元素的 equals() 方法来确定该元素是否等于要替换的元素。

  

unmodifiableSet() 不可变集合

unmodifiableSet() 方法可以从普通 Java 集合创建不可变(不可修改)的集合。例如:

package com.hxstrive.java_collection;

import java.util.Set;
import java.util.HashSet;
import java.util.Collections;

public class UnmodifiableSetDemo {
    public static void main(String[] args) {
        // 创建普通的HashSet并添加元素
        Set<String> normalSet = new HashSet<>();
        normalSet.add("Apple");
        normalSet.add("Banana");
        normalSet.add("Cherry");
        System.out.println("普通集合元素: " + normalSet);
        
        // 创建不可修改的集合视图
        Set<String> immutableSet = Collections.unmodifiableSet(normalSet);
        System.out.println("不可修改集合元素: " + immutableSet);
        
        // 尝试修改不可修改的集合(会抛出异常)
        try {
            immutableSet.add("Date");
        } catch (UnsupportedOperationException e) {
            System.out.println("尝试添加元素到不可修改集合时的异常: " + e.getMessage());
        }
        
        try {
            immutableSet.remove("Apple");
        } catch (UnsupportedOperationException e) {
            System.out.println("尝试删除元素时的异常: " + e.getMessage());
        }
        
        // 修改原始集合会影响不可修改集合的内容
        normalSet.add("Elderberry");
        System.out.println("\n原始集合修改后,不可修改集合的内容: " + immutableSet);
    }
}

运行结果:

普通集合元素: [Apple, Cherry, Banana]
不可修改集合元素: [Apple, Cherry, Banana]
尝试添加元素到不可修改集合时的异常: null
尝试删除元素时的异常: null

原始集合修改后,不可修改集合的内容: [Apple, Cherry, Elderberry, Banana]

到这里,我们介绍了 Collections 工具类中最常用的方法,更多方法的用法请参考 https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html API 文档。

  

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号