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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:13:04  来源:igfitidea点击:

Java 8 Stream API to find Unique Object matching a property value

javafilterjava-8java-stream

提问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.

不要使用收集器,而是尝试使用findFirstfindAny

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或更好,使用ifPresentmaporElse或任何其他的替代品在发现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参考路线。在可选类(其他替代方法ifPresentmap等等)可以解决许多使用情况。我发现自己使用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():

通过使用findAny()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()。)