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. 创建不可变的 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
}
}
应用场景
-
配置数据:在配置文件中存储固定的配置数据,这些数据在程序运行期间不会改变。
Map<String, String> config = Map.of("host", "localhost", "port", "8080");
-
常量集合:定义一组常量,这些常量在整个应用中多次使用。
List<String> weekdays = List.of("Monday", "Tuesday", "Wednesday", "Thursday", "Friday");
-
缓存:在缓存中存储不可变的数据,确保数据的一致性和安全性。
Map<String, User> userCache = Map.of("user1", new User("John"), "user2", new User("Jane"));
-
初始化数据:在初始化阶段创建固定的集合,避免后续的修改。
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 } }