Java 9的到来为Java的Collections API带来了许多新功能,其中一个是集合工厂方法。
它们是什么以及如何正确实施?
答案 0 :(得分:9)
注1:为了防止使用raw-types,我选择使用E
为我在下面提到的每个类提供泛型类型,表示{的一个元素{1}}。子> 子>
注2:这个答案可能会有所变化;如果发生拼写错误,请编辑此帖子。
Java中的集合工厂方法是一种静态方法,它提供了一种初始化不可变 Collection<E>
的简单方法。
不可变,在初始化Collection<E>
后,Collection<E>
内无法添加,删除或修改任何元素。
使用Java 9,为以下接口提供了集合工厂方法:List<E>
,Set<E>
和Map<K, V>
直到Java 9,没有简单的通用方法来初始化具有初始元素/键值条目的Collection<E>
。以前,开发人员需要按如下方式初始化它们(假设通用类型E
,K
和V
已替换为Integer
):
List<Integer>
List<Integer>
,但结果只是List<Integer>
的视图;我们无法添加或删除此List<Integer>
,但我们仍然可以使用List#set
修改现有元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer>
完全可变,那么我们必须将它传递给ArrayList<Integer>
的构造函数,例如:
List<Integer> mutableList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Set<Integer>
Set<Integer>
需要使用初始元素进行初始化的代码多于List<Integer>
(使用初始元素初始化List<Integer>
需要Set<Integer>
),可以在下面看到。
Set<Integer> mutableSet = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
Map<Integer, Integer>
Map<Integer, Integer>
可能是最复杂的;但是,有多种方法可以解决这个问题。
Map<Integer, Integer>
,然后只需调用Map#put
即可添加键值条目。Map#put
。我认为集合工厂方法为开发人员提供了一种初始化List<E>
,Set<E>
或Map<K, V>
的简明方法,其中包含初始元素/键值条目,可以看到通过以下示例。
为简单起见,这些示例将使用E
替换通用类型K
,V
和Integer
。
List<Integer>
List<Integer> list = List.of();
List<Integer>
。List<Integer> list = List.of(1);
List<Integer>
。List<Integer> list = List.of(1, 2);
List<Integer>
。List<Integer> list = List.of(1, 2, 3, 4, 5, ...);
List<Integer>
。Set<Integer>
Set<Integer> set = Set.of();
Set<Integer>
。Set<Integer> set = Set.of(1);
Set<Integer>
。Set<Integer> set = Set.of(1, 2);
Set<Integer>
。Set<Integer> set = Set.of(1, 2, 3, 4, 5, ...);
Set<Integer>
。Map<Integer, Integer>
Map<Integer, Integer> map = Map.of();
Map<Integer, Integer>
。Map<Integer, Integer> map = Map.of(1, 2);
Map<Integer, Integer>
。1
,值为2
。Map<Integer, Integer> map = Map.of(1, 2, 3, 4);
Map<Integer, Integer>
。1
和3
,值为2
和4
。Map<Integer, Integer> map = Map.ofEntries(Map.entry(1, 2), Map.entry(3, 4), ...);
Map<Integer, Integer>
。正如您所看到的,这种新的初始化方法需要的代码少于其前辈。
由集合工厂方法创建的Collection<E>
本质上是不可变的,但是我们能够将它们传递给Collection<E>
的实现的构造函数以生成可变版本:
List<Integer>
List<Integer> mutableList = new ArrayList<>(List.of(1, 2, 3, 4, 5));
Set<Integer>
Set<Integer> mutableSet = new HashSet<>(Set.of(1, 2, 3, 4, 5));
Map<Integer, Integer>
Map<Integer, Integer> mutableMap = new HashMap<>(Map.of(1, 2, 3, 4));