Java 9:什么是集合工厂方法?
Java 9的到来为Java的Collections API带来了许多新function,其中一个是集合工厂方法。
它们是什么以及如何正确实施它们?
注1:为了防止使用原始类型,我选择为下面提到的每个类提供一个generics类型,使用E
代表Collection
一个元素。
注2:这个答案可能会有所变化; 如果发生拼写错误,请编辑此post。
什么是收集工厂方法?
Java中的集合工厂方法是一种静态方法,它提供了一种初始化不可变 Collection
的简单方法。
作为不可变的,在初始化之后, Collection
不能添加,删除或修改元素。
使用Java 9,为以下接口提供了集合工厂方法: List
, Set
和Map
它们有什么改进?
直到Java 9,没有简单的通用方法来初始化具有初始元素/键值条目的Collection
。 以前,开发人员需要按如下方式初始化它们(假设通用类型E
, K
和V
已被Integer
替换):
-
List
- 下面的方法可以说是最简单的用初始元素初始化
List
,但结果只是List
的视图; 我们无法添加或删除此List
,但我们仍然可以使用List#set
修改现有元素。-
List
list = Arrays.asList(1, 2, 3, 4, 5);
-
- 如果我们希望
List
完全可变,那么我们必须将它传递给ArrayList
的构造函数,例如:-
List
mutableList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
-
- 下面的方法可以说是最简单的用初始元素初始化
-
Set
-
Set
需要更多代码来初始化初始元素而不是List
(使用初始元素初始化Set
需要看到List
),这可以在下面看到。-
Set
mutableSet = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
-
-
-
Map
- 使用初始键值条目初始化时,
Map
可能是最复杂的; 但是,有多种方法可以解决这个问题。- 一种方法是首先初始化一个空的
Map
然后简单地调用Map#put
来添加键值条目。 - 另一种方法是使用带有两个花括号的匿名类,这仍然需要调用
Map#put
。
- 一种方法是首先初始化一个空的
- 使用初始键值条目初始化时,
我为什么要用它们?
我认为集合工厂方法为开发人员提供了一个简洁的方法,用初始元素/键值条目初始化List
, Set
或Map
,这可以通过下面的例子看到。
使用的正确语法是什么?
为简单起见,这些示例将用Integer
替换generics类型E
, K
和V
-
List
-
List
list = List.of(); - 初始化一个空的,不可变的
List
。
- 初始化一个空的,不可变的
-
List
list = List.of(1); - 使用一个元素初始化不可变
List
。
- 使用一个元素初始化不可变
-
List
list = List.of(1, 2); - 使用两个元素初始化不可变
List
。
- 使用两个元素初始化不可变
-
List
list = List.of(1, 2, 3, 4, 5, ...); - 使用可变数量的元素初始化不可变
List
。
- 使用可变数量的元素初始化不可变
-
-
Set
-
Set
set = Set.of(); - 初始化一个空的,不可变的
Set
。
- 初始化一个空的,不可变的
-
Set
set = Set.of(1); - 使用一个元素初始化一个不可变的
Set
。
- 使用一个元素初始化一个不可变的
-
Set
set = Set.of(1, 2); - 使用两个元素初始化一个不可变的
Set
。
- 使用两个元素初始化一个不可变的
-
Set
set = Set.of(1, 2, 3, 4, 5, ...); - 使用可变数量的元素初始化不可变的
Set
。
- 使用可变数量的元素初始化不可变的
-
-
Map
-
Map
map = Map.of(); - 初始化一个空的,不可变的
Map
。
- 初始化一个空的,不可变的
-
Map
map = Map.of(1, 2); - 使用一个键值条目初始化不可变
Map
。 - 请注意,键为
1
,值为2
。
- 使用一个键值条目初始化不可变
-
Map
map = Map.of(1, 2, 3, 4); - 使用两个键值条目初始化不可变
Map
。 - 请注意,键为
1
和3
,值为2
和4
。
- 使用两个键值条目初始化不可变
-
Map
map = Map.ofEntries(Map.entry(1, 2), Map.entry(3, 4), ...); - 使用可变数量的键值条目初始化不可变
Map
。
- 使用可变数量的键值条目初始化不可变
-
如您所见,这种新的初始化方法需要的代码少于其前辈。
我可以使用集合工厂方法来创建可变对象吗?
由集合工厂方法创建的Collection
本质上是不可变的,但是我们能够将它们传递给Collection
的实现的构造函数以生成可变版本:
-
List
-
List
mutableList = new ArrayList<>(List.of(1, 2, 3, 4, 5));
-
-
Set
-
Set
mutableSet = new HashSet<>(Set.of(1, 2, 3, 4, 5));
-
-
Map
-
Map
mutableMap = new HashMap<>(Map.of(1, 2, 3, 4));
-
- Java中的StringIndexOutOfBounds
- getCurrentSession在web中进行hibernate
- Eclipse没有使用由NoClassDefFoundError引起的JUnit 5的测试
- 将ZipEntry复制到新ZipFile的惯用方法是什么?
- 如何在jdk9 / java-9中使用sun.reflect包?
- 在Spring Security中实现自定义身份validation
- 在java正则表达式中捕获组的行为混淆
- java.lang.ClassCastException:无法强制转换java.util.LinkedHashMap
- 在grails控制器中识别ajax请求或浏览器请求