Java 9 集合工厂方法

Java 9 引入了集合工厂方法,用于创建不可变集合。这些方法简化了创建固定大小的集合的过程,并且这些集合是线程安全的,不允许添加、删除或修改元素。这在很多场景下非常有用,特别是当你需要创建小型、固定的集合时。

主要方法
  • List.of(E... elements):创建一个不可变的 List
  • Set.of(E... elements):创建一个不可变的 Set
  • Map.of(K k1, V v1, K k2, V v2, ...):创建一个不可变的 Map,最多支持 10 个键值对。
  • Map.ofEntries(Map.Entry<K,V>... entries):创建一个不可变的 Map,使用 Map.entry(K, V) 方法创建键值对。
特点
  1. 不可变:创建的集合是不可变的,不能添加、删除或修改元素。
  2. 线程安全:由于不可变性,这些集合是线程安全的。
  3. 性能优化:不可变集合在某些情况下可以提高性能,因为它们不需要同步机制。

示例代码

1. 创建不可变的 List
import java.util.List;

public class ImmutableListExample {
    public static void main(String[] args) {
        List<String> list = List.of("Apple", "Banana", "Cherry");
        System.out.println(list); // 输出: [Apple, Banana, Cherry]

        // 尝试修改列表会抛出 UnsupportedOperationException
        // list.add("Date"); // 抛出 UnsupportedOperationException
    }
}
2. 创建不可变的 Set
import java.util.Set;

public class ImmutableSetExample {
    public static void main(String[] args) {
        Set<String> set = Set.of("Apple", "Banana", "Cherry");
        System.out.println(set); // 输出: [Apple, Banana, Cherry]

        // 尝试修改集合会抛出 UnsupportedOperationException
        // set.add("Date"); // 抛出 UnsupportedOperationException
    }
}
3. 创建不可变的 Map
import java.util.Map;

public class ImmutableMapExample {
    public static void main(String[] args) {
        // 使用 Map.of 创建不可变的 Map
        Map<String, Integer> map = Map.of("Apple", 1, "Banana", 2, "Cherry", 3);
        System.out.println(map); // 输出: {Apple=1, Banana=2, Cherry=3}

        // 使用 Map.ofEntries 创建不可变的 Map
        Map<String, Integer> map2 = Map.ofEntries(
            Map.entry("Apple", 1),
            Map.entry("Banana", 2),
            Map.entry("Cherry", 3)
        );
        System.out.println(map2); // 输出: {Apple=1, Banana=2, Cherry=3}

        // 尝试修改映射会抛出 UnsupportedOperationException
        // map.put("Date", 4); // 抛出 UnsupportedOperationException
    }
}

应用场景

  1. 配置数据:在配置文件中存储固定的配置数据,这些数据在程序运行期间不会改变。

    Map<String, String> config = Map.of("host", "localhost", "port", "8080");
    
  2. 常量集合:定义一组常量,这些常量在整个应用中多次使用。

    List<String> weekdays = List.of("Monday", "Tuesday", "Wednesday", "Thursday", "Friday");
    
  3. 缓存:在缓存中存储不可变的数据,确保数据的一致性和安全性。

    Map<String, User> userCache = Map.of("user1", new User("John"), "user2", new User("Jane"));
    
  4. 初始化数据:在初始化阶段创建固定的集合,避免后续的修改。

    Set<String> validCommands = Set.of("start", "stop", "restart");
    

注意事项

  • 重复元素:在创建 Set 时,如果传入的元素有重复,Set.of 会抛出 IllegalArgumentException
    Set<String> set = Set.of("Apple", "Apple", "Banana"); // 抛出 IllegalArgumentException
    
  • 空值:在创建集合时,如果传入 null,会抛出 NullPointerException
    List<String> list = List.of("Apple", null, "Cherry"); // 抛出 NullPointerException
    

List 不同创建方式的对比

有小伙伴会问了,在 Java 中,有多种方式可以创建 List,我咋选啊。以下是一些常见的创建 List 的方式及其对比:

1. new ArrayList<>()

  • 特点:创建一个可变的、动态的列表。
  • 适用场景:适用于需要频繁添加、删除或修改元素的场景。
  • 示例
    import java.util.ArrayList;
    import java.util.List;
    
    public class ArrayListExample {
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            list.add("Apple");
            list.add("Banana");
            list.add("Cherry");
            System.out.println(list); // 输出: [Apple, Banana, Cherry]
            list.add("Date");
            System.out.println(list); // 输出: [Apple, Banana, Cherry, Date]
        }
    }
    

2. Arrays.asList()

  • 特点:创建一个固定大小的列表,基于数组实现。
  • 适用场景:适用于需要创建固定大小的列表,并且需要修改现有元素的场景。
  • 示例
    import java.util.Arrays;
    import java.util.List;
    
    public class ArraysAsListExample {
        public static void main(String[] args) {
            List<String> list = Arrays.asList("Apple", "Banana", "Cherry");
            System.out.println(list); // 输出: [Apple, Banana, Cherry]
            list.set(0, "Apricot");
            System.out.println(list); // 输出: [Apricot, Banana, Cherry]
            // 尝试添加元素会抛出 UnsupportedOperationException
            // list.add("Date"); // 抛出 UnsupportedOperationException
        }
    }
    

3. List.of()

  • 特点:创建一个不可变的列表。
  • 适用场景:适用于需要创建固定内容的列表,且列表内容在创建后不会改变的场景。
  • 示例
    import java.util.List;
    
    public class ListOfExample {
        public static void main(String[] args) {
            List<String> list = List.of("Apple", "Banana", "Cherry");
            System.out.println(list); // 输出: [Apple, Banana, Cherry]
            // 尝试修改列表会抛出 UnsupportedOperationException
            // list.add("Date"); // 抛出 UnsupportedOperationException
        }
    }
    

4. Collections.singletonList()

  • 特点:创建一个只包含单个元素的不可变列表。
  • 适用场景:适用于需要创建只包含一个元素的列表的场景。
  • 示例
    import java.util.Collections;
    import java.util.List;
    
    public class SingletonListExample {
        public static void main(String[] args) {
            List<String> list = Collections.singletonList("Apple");
            System.out.println(list); // 输出: [Apple]
            // 尝试修改列表会抛出 UnsupportedOperationException
            // list.add("Banana"); // 抛出 UnsupportedOperationException
        }
    }
    

5. Collections.emptyList()

  • 特点:创建一个空的不可变列表。
  • 适用场景:适用于需要创建一个空列表的场景。
  • 示例
    import java.util.Collections;
    import java.util.List;
    
    public class EmptyListExample {
        public static void main(String[] args) {
            List<String> list = Collections.emptyList();
            System.out.println(list); // 输出: []
            // 尝试修改列表会抛出 UnsupportedOperationException
            // list.add("Apple"); // 抛出 UnsupportedOperationException
        }
    }
    

6. Collections.unmodifiableList()

  • 特点:将现有的列表转换为不可变列表。
  • 适用场景:适用于需要将一个可变列表转换为不可变列表的场景。
  • 示例
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class UnmodifiableListExample {
        public static void main(String[] args) {
            List<String> mutableList = new ArrayList<>();
            mutableList.add("Apple");
            mutableList.add("Banana");
            mutableList.add("Cherry");
    
            List<String> unmodifiableList = Collections.unmodifiableList(mutableList);
            System.out.println(unmodifiableList); // 输出: [Apple, Banana, Cherry]
            // 尝试修改列表会抛出 UnsupportedOperationException
            // unmodifiableList.add("Date"); // 抛出 UnsupportedOperationException
        }
    }
    

比较总结

11-14 17:28