当我们创建空的不可变列表/集合/映射时,是否有任何实际的应用程序/用例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当我们创建空的不可变列表/集合/映射时,是否有任何实际的应用程序/用例相关的知识,希望对你有一定的参考价值。
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就可以在不复制任何内容的情况下提交对内部列表的引用。现在,该列表迟早必须为空,需要一个空的不可变列表。
以上是关于当我们创建空的不可变列表/集合/映射时,是否有任何实际的应用程序/用例的主要内容,如果未能解决你的问题,请参考以下文章