Tra*_*ity 25 java equality java-stream
所以如果我有一个Name对象并且有一个ArrayListtype Name(names),并且我想确定我的名字列表是否包含给定的Name对象(n),我可以用两种方式做到:
boolean exists = names.contains(n);
Run Code Online (Sandbox Code Playgroud)
要么
boolean exists - names.stream().anyMatch(x -> x.equals(n));
Run Code Online (Sandbox Code Playgroud)
我正在考虑这两个是否会表现相同,然后考虑如果分配n会发生什么null?
对于contains,据我所知,如果参数是null,则true在列表包含时返回null.我将如何实现这一点anyMatch- 是否可以通过使用Objects.equals(x, n)?
如果可行,那么哪种方法更有效 - 是否anyMatch可以利用懒惰和并行性?
Mar*_*o13 27
基于流的版本的问题在于,如果集合(及其流)包含null元素,则谓词将NullPointerException在尝试调用equals此null对象时抛出.
这可以避免
boolean exists = names.stream().anyMatch(x -> Objects.equals(x, n));
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,基于流的解决方案没有实际的优势.并行性可能会为真正的大型列表带来优势,但是不应该随便扔掉一些parallel()假设它可能会让事情更快.首先,您应该清楚地确定实际的瓶颈.
就可读性而言,我更喜欢这里的第一个经典解决方案.如果你想检查列表是否names.contains(aParticularValue),你应该这样做 - 它只是读起来像散文,并使意图明确.
编辑
在的另一个优点contains方法评价和在其他的答案中提到,这可能是这里值得一提:如果类型names集合后改变,例如,是一个HashSet,那么你会得到更快的contains-check (免费使用O(1)而不是O(n)) - 不更改代码的任何其他部分.然后,基于流的解决方案仍然必须遍历所有元素,这可能会显着降低性能.