怎样操作,使得一个集合不可被修改?

参考回答**

在 Java 中,如果需要使一个集合不可修改(即对集合的任何修改操作都会抛出异常),可以通过以下几种方法来实现。常用的方法是使用 Collections.unmodifiableXXXList.of(适用于 Java 9 及以上版本)。


实现方式

1. 使用 Collections.unmodifiableXXX

  • 简介
    • Java 提供了 Collections 类中的 unmodifiableXXX 方法,可以将一个现有的集合包装成不可修改的集合。
    • 适用于ListSetMap 等所有主要集合类型。
  • 特点
    • 返回的集合是一个包装对象,原始集合的内容仍然可以通过原始引用修改,但包装后的集合不允许修改。
    • 如果通过包装后的不可修改集合尝试修改操作,则会抛出 UnsupportedOperationException
  • 代码示例
    import java.util.*;
    
    public class UnmodifiableCollectionExample {
      public static void main(String[] args) {
          List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
    
          // 将集合包装为不可修改的集合
          List<String> unmodifiableList = Collections.unmodifiableList(list);
    
          System.out.println(unmodifiableList); // 输出:[A, B, C]
    
          // 尝试修改
          // unmodifiableList.add("D"); // 抛出 UnsupportedOperationException
    
          // 修改原始集合
          list.add("D");
          System.out.println(unmodifiableList); // 输出:[A, B, C, D]
      }
    }
    
  • 适用方法
    • Collections.unmodifiableList(Collection c)
    • Collections.unmodifiableSet(Set s)
    • Collections.unmodifiableMap(Map m)

2. 使用 List.ofSet.ofMap.of(Java 9+)

  • 简介
    • 从 Java 9 开始,List.ofSet.ofMap.of 方法可以创建不可修改的集合。

    • unmodifiableXXX 的区别

    • List.of 创建的集合本身就是不可修改的,并且不能通过原始集合引用修改。
    • List.of 创建的集合不允许包含 null 元素。
  • 代码示例
    import java.util.*;
    
    public class ImmutableCollectionExample {
      public static void main(String[] args) {
          // 创建不可修改的集合
          List<String> list = List.of("A", "B", "C");
          System.out.println(list); // 输出:[A, B, C]
    
          // 尝试修改
          // list.add("D"); // 抛出 UnsupportedOperationException
    
          // 尝试添加 null
          // List<String> listWithNull = List.of("A", null); // 抛出 NullPointerException
      }
    }
    
  • 适用方法
    • List.of(E... elements):创建不可修改的列表。
    • Set.of(E... elements):创建不可修改的集合。
    • Map.of(K key, V value, ...):创建不可修改的映射。

3. 使用 Collections.unmodifiableXXX + 自定义类

  • 如果需要一个自定义不可修改集合,可以结合 Collections.unmodifiableXXX 和继承来实现不可修改的行为。

示例

import java.util.*;

class CustomImmutableList extends ArrayList<String> {
    @Override
    public boolean add(String s) {
        throw new UnsupportedOperationException("Cannot modify this collection");
    }

    @Override
    public boolean remove(Object o) {
        throw new UnsupportedOperationException("Cannot modify this collection");
    }
}

public class CustomImmutableExample {
    public static void main(String[] args) {
        List<String> customImmutableList = new CustomImmutableList();
        customImmutableList.add("A"); // 抛出 UnsupportedOperationException
    }
}

操作后集合不可修改的主要实现方式对比

方法 特性 适用场景
Collections.unmodifiableXXX 原集合可以修改,但包装后的集合不允许修改 动态生成集合后需要防止外部修改
List.of / Set.of 创建的集合本身不可修改,且不允许 null 元素 集合内容固定,适合常量集合的初始化
自定义不可修改类 通过继承或包装实现完全不可修改的集合,禁止任何直接或间接修改操作 更灵活的场景,结合特定需求自定义不可修改行为

4. 其他方式

4.1 使用第三方库

如果需要更强大的不可修改集合功能,可以使用一些第三方库,如:

  • Google Guava 提供了 ImmutableListImmutableSetImmutableMap,这些集合是完全不可修改的。

  • 示例代码

    import com.google.common.collect.ImmutableList;
    
    public class GuavaImmutableExample {
      public static void main(String[] args) {
          ImmutableList<String> list = ImmutableList.of("A", "B", "C");
    
          System.out.println(list); // 输出:[A, B, C]
    
          // list.add("D"); // 抛出 UnsupportedOperationException
      }
    }
    

4.2 使用 Stream 构建不可修改集合

从 Java 10 开始,Collectors.toUnmodifiableList() 提供了一种流式构建不可修改集合的方式。

  • 代码示例

    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    public class StreamImmutableExample {
      public static void main(String[] args) {
          List<String> list = Stream.of("A", "B", "C")
                  .collect(Collectors.toUnmodifiableList());
    
          System.out.println(list); // 输出:[A, B, C]
    
          // list.add("D"); // 抛出 UnsupportedOperationException
      }
    }
    

总结

方法 是否允许修改原集合 是否允许包含 null Java 版本
Collections.unmodifiableXXX 允许 允许 Java 1.2
List.of / Set.of 不允许 不允许 Java 9+
Google Guava ImmutableList 不允许 不允许 Guava 库
Stream.toUnmodifiableList 不允许 不允许 Java 10+

推荐

  • 使用 Collections.unmodifiableXXX:如果需要防止外部对动态集合的修改。
  • 使用 List.ofSet.of:如果集合内容固定,并且需要不可变的集合。

发表评论

后才能评论