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.toListso 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 findFirstor findAny.
不要使用收集器,而是尝试使用findFirst或findAny。
Optional<Person> matchingObject = objects.stream().
filter(p -> p.email().equals("testemail")).
findFirst();
This returns an Optionalsince 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!getthrows NoSuchElementExceptionif no value is present. Therefore it is strongly advised that you first ensure that the value is present (either with isPresentor better, use ifPresent, map, orElseor any of the other alternatives found in the Optionalclass).
不过要小心!如果不存在任何值,则get抛出NoSuchElementException。因此,我们强烈建议您先确保该值存在(或者使用isPresent或更好,使用ifPresent,map,orElse或任何其他的替代品在发现Optional类)。
If you're okay with a nullreference if there is no such person, then:
如果null没有这样的人,您可以接受参考,那么:
Person person = matchingObject.orElse(null);
If possible, I would try to avoid going with the nullreference route though. Other alternatives methods in the Optional class (ifPresent, mapetc) 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 nullreferences 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 IllegalArgumentExceptionif the stream consists of two or more elements, and a NoSuchElementExceptionif 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()。)

