Collections.emptyMap() vs new HashMap()
我可以在哪些情况下使用
为什么我要一个不变的空集合?有什么意义?
从有效的Java中,Typeα43(EDCOX1)1表示要返回一个空集合,甚至可能演示使用这些EDCOX1、2、EDCOX1、3、EDCX1、4个方法在集合类中获得一个空集合,这也具有不可变的额外好处。来自项目15
从集合EmptySet集合EmptyList集合
Its a type of programming idiom. This is for people that do not want null variables. So before the set gets initialized, they can use the empty set.
注意:下面的代码只是一个例子(根据您的用例更改它):
1 2 3 4 5 6 7 8 | private Set myset = Collections.emptySet(); void initSet() { myset = new HashSet(); } void deleteSet() { myset = Collections.emptySet(); } |
这些方法有两个优点:
它们更简洁,因为您不需要显式地键入集合的泛型类型——通常只是从方法调用的上下文推断出来的。
它们效率更高,因为它们不需要创建新对象;它们只是重用现有的空的和不变的对象。这种影响通常很小,但偶尔(好吧,很少)很重要。
诚然,在我个人的经验中,它在API需要参数集合但您没有提供的情况下非常有用。例如,您可能有这样一个API,它不允许空引用:
如果您有一个不带任何参数的查询,那么创建一个hashmap肯定有点浪费,它涉及到分配一个数组,当您可以传入一个"空映射"时,它实际上是一个常量,它在
Why would I want an immutable empty collection? What is the point?
这里有两个不同的概念,在一起看时会显得很奇怪。当你分别对待这两个概念时,这就更有意义了。
首先,您应该尽可能使用不可变集合,而不是可变集合。不动产的好处在别处有很好的记载。
其次,您应该更喜欢使用空集合,而不是将空集合用作哨兵。这里很好地描述了这一点。这意味着您将拥有更干净、更容易理解的代码,而隐藏bug的地方更少。
因此,当您有需要映射的代码时,最好传递一个空映射,而不是一个空映射来表示没有映射。大多数时候,当你使用一个地图时,最好使用一个不变的地图。所以这就是为什么有一个方便的函数来生成一个不变的空映射。
在某些情况下,您更喜欢使用不可变的映射、列表、集合或其他类型的集合。
首先,也可以说是最重要的用例是,每当您返回一个查询结果或一个将返回一组(或列表或映射)结果的计算结果时,您应该更喜欢使用不可变的数据结构。
在这种情况下,我更倾向于返回这些不可变的版本,因为这更清楚地反映了计算结果集的事实不可变性-无论以后如何处理数据,从查询中收到的结果集都不应更改。
第二个常见的用例是当您需要提供一个参数作为方法或服务的输入时。除非您希望输入集合被服务或方法修改(这通常是一个非常糟糕的设计思想),否则在许多情况下,传入不可变集合而不是可变集合可能是合理和安全的选择。
我认为这是"传递价值"的惯例。
更一般地说,当数据跨越模块或服务边界时,使用不变的数据结构是一种明智的做法。这使得解释(不可变的)输入/输出和可变的内部状态之间的差异更加容易。
这样做的一个非常有益的副作用是提高模块/服务的安全性和线程安全性,并确保更清晰地分离关注点。
使用
只需比较这两个声明:
1 | Map<Foo, Comparable<? extends Bar>> fooBarMap = new HashMap<Foo, Comparable<? extends Bar>>(); |
对比:
1 |
后者显然以两种重要方式赢得可读性:
首先,你可以通过分享参考资料来摆脱困境。
我建议检查一下Josh Bloch的有效Java,它列出了一些不可变对象(包括线程安全)的非常好的属性。
当您有返回
它使您的代码更容易,并防止
大多数时候,我们使用一个
They're more concise because you don't need to explicitly type out the generic type of the collection - it's generally just inferred from
the context of the method call.They're more efficient because they don't bother creating new objects; they just re-use an existing empty and immutable object. This
effect is generally very minor, but it's occasionally (well, rarely)
important.
Why would I want an immutable empty collection? What is the point?
出于同样的原因,您在某些时候会使用
Why would I want an immutable empty collection? What is the point?
出于同样的原因,您可能需要不可变的对象。主要是因为您可以在夜间安全睡眠,因为您知道多个线程可以访问一个对象的同一个实例,并且它们都将看到相同的值。集合中没有任何项仍然是一个有效值,您需要维护该值。