Java 8 Stream API 查找与属性值匹配的唯一对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33992479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 Stream API to find Unique Object matching a property value
提问by Santosh
Find the object matching with a Property value from a Collection using Java 8 Stream.
使用 Java 8 Stream 从集合中查找与属性值匹配的对象。
List<Person> objects = new ArrayList<>();
Person attributes -> Name, Phone, Email.
人员属性 -> 姓名、电话、电子邮件。
Iterate through list of Persons and find object matching email. Saw that this can be done through Java 8 stream easily. But that will still return a collection?
遍历人员列表并找到与电子邮件匹配的对象。看到这可以通过 Java 8 流轻松完成。但这仍然会返回一个集合?
Ex:
前任:
List<Person> matchingObjects = objects.stream.
filter(p -> p.email().equals("testemail")).
collect(Collectors.toList());
But I know that it will always have one unique object. Can we do something instead of Collectors.toList
so that i got the actual object directly.Instead of getting the list of objects.
但我知道它总会有一个独特的对象。我们能不能做点什么,而不是Collectors.toList
让我直接得到实际的对象。而不是获取对象列表。
采纳答案by Indrek Ots
Instead of using a collector try using findFirst
or findAny
.
不要使用收集器,而是尝试使用findFirst
或findAny
。
Optional<Person> matchingObject = objects.stream().
filter(p -> p.email().equals("testemail")).
findFirst();
This returns an Optional
since the list might not contain that object.
这将返回 ,Optional
因为列表可能不包含该对象。
If you're sure that the list always contains that person you can call:
如果您确定列表中始终包含您可以致电的人:
Person person = matchingObject.get();
Be careful though!get
throws NoSuchElementException
if no value is present. Therefore it is strongly advised that you first ensure that the value is present (either with isPresent
or better, use ifPresent
, map
, orElse
or any of the other alternatives found in the Optional
class).
不过要小心!如果不存在任何值,则get
抛出NoSuchElementException
。因此,我们强烈建议您先确保该值存在(或者使用isPresent
或更好,使用ifPresent
,map
,orElse
或任何其他的替代品在发现Optional
类)。
If you're okay with a null
reference if there is no such person, then:
如果null
没有这样的人,您可以接受参考,那么:
Person person = matchingObject.orElse(null);
If possible, I would try to avoid going with the null
reference route though. Other alternatives methods in the Optional class (ifPresent
, map
etc) can solve many use cases. Where I have found myself using orElse(null)
is only when I have existing code that was designed to accept null
references in some cases.
如果可能,我会尽量避免使用null
参考路线。在可选类(其他替代方法ifPresent
,map
等等)可以解决许多使用情况。我发现自己使用orElse(null)
的地方只有当我拥有旨在null
在某些情况下接受引用的现有代码时。
Optionals have other useful methods as well. Take a look at Optional javadoc.
Optionals 还有其他有用的方法。看看Optional javadoc。
回答by Sahil Chhabra
Guava API provides MoreCollectors.onlyElement() which is a collector that takes a stream containing exactly one elementand returns that element.
Guava API 提供了MoreCollectors.onlyElement(),它是一个收集器,它接收一个包含一个元素的流并返回该元素。
The returned collector throwsan IllegalArgumentException
if the stream consists of two or more elements, and a NoSuchElementException
if the stream is empty.
返回的集电极抛出一个IllegalArgumentException
如果流包括两个或更多个元件的,以及NoSuchElementException
如果该流是空的。
Refer the below code for usage:
使用方法参考以下代码:
import static com.google.common.collect.MoreCollectors.onlyElement;
Person matchingPerson = objects.stream
.filter(p -> p.email().equals("testemail"))
.collect(onlyElement());
回答by Bijaya Bhaskar Swain
findAny
& orElse
findAny
& orElse
By using findAny()
and orElse()
:
Person matchingObject = objects.stream().
filter(p -> p.email().equals("testemail")).
findAny().orElse(null);
Stops looking after finding an occurrence.
发现事件后停止查找。
findAny
Optional<T>?findAny()
Returns an Optional describing some element of the stream, or an empty Optional if the stream is empty. This is a short-circuiting terminal operation. The behavior of this operation is explicitly nondeterministic; it is free to select any element in the stream. This is to allow for maximal performance in parallel operations; the cost is that multiple invocations on the same source may not return the same result. (If a stable result is desired, use findFirst() instead.)
findAny
Optional<T>?findAny()
返回描述流的某些元素的 Optional,如果流为空,则返回空的 Optional。这是短路端子操作。此操作的行为明显是不确定的;可以自由选择流中的任何元素。这是为了在并行操作中实现最大性能;代价是对同一源的多次调用可能不会返回相同的结果。(如果需要稳定的结果,请改用 findFirst()。)