Java 9提供了一种创建Empty immutable List,set和Map的方法。
List list = List.of();
Set set = Set.of();
Map map = Map.of();
但是我无法理解创建空的不可变列表/集合/映射的实际用例是什么。
请帮助我理解一个空的不可变列表/ set / map的实际用例。
在Java 9之前,有Collections.emptyList()
,Collections.emptySet()
和Collections.emptyMap()
,它们明确地且专门用于生成不可修改的空集合。 List.of()
等也可以这样做是他们的API的内部一致性问题,而不是革命性的新功能。
但你的主要问题似乎是
请帮助我理解一个空的不可变列表/ set / map的实际用例。
这真的有三个问题:
此外,您没有问过,但可能忽略了这一点,虽然您无法将对象添加到不可修改的空集合中,但您可以将其替换为非空集合,或者在下次提供非空集合时使用,或者类似。
想象一下应该对这些集合进行操作的常规数学运算。就像计算列表的交集一样。结果可以为空,在这种情况下,如果结果应该是不可变的,那么这个方法会很有用。
public List<E> intersectLists(List<E> first, List<E> second) {
// If one is empty, return empty list
if (first.isEmpty() || second.isEmpty()) {
// Before Java 9: return Collections.emptyList();
return List.of();
}
// Compute intersection
...
}
当您通过getter公开内部数据结构但不希望调用者能够操作集合时,通常会使用不可变集合。
类似的变体是不可修改的集合。如果您直接引用位于包装器下方的可变集合,则可以对这些进行操作。通过这种方式,您可以强制用户使用您指定的方法进行操作。
public Graph {
private List<Node> nodes;
// Other stuff
...
public List<Node> getNodes() {
// Wrap container to make list unmodifiable
return Collections.unmodifiableList(nodes);
}
// User should use designated methods to manipulate instead
public void addNode(Node node) { ... }
public void removeNode(Node node) { ... }
}
每当类暴露内部集合(通过公共属性,getter等)时,它必须复制整个集合或公开不可变集合,以避免调用者操纵内部数据结构。
例如,你可以有一些在内部使用但也通过getter公开的整数列表。由于列表不经常更新但经常读取,因此您决定使内部列表不可变(在每次更新时创建一个新列表)。这样你的getter就可以在不复制任何内容的情况下提交对内部列表的引用。现在,该列表迟早必须为空,需要一个空的不可变列表。