用于查找与属性值匹配的唯一对象的Java8流API

用于查找与属性值匹配的唯一对象的Java8流API,java,filter,java-8,java-stream,Java,Filter,Java 8,Java Stream,使用Java8流从集合中查找与属性值匹配的对象 List<Person> objects = new ArrayList<>(); List objects=new ArrayList(); 人员属性->姓名、电话、电子邮件 遍历人员列表并查找与电子邮件匹配的对象。 看到了这可以通过Java8流轻松完成。但这仍然会返回一个集合 例: List matchingObjects=objects.stream。 过滤器(p->p.email().equals(“testem

使用Java8流从集合中查找与属性值匹配的对象

List<Person> objects = new ArrayList<>();
List objects=new ArrayList();
人员属性->姓名、电话、电子邮件

遍历人员列表并查找与电子邮件匹配的对象。 看到了这可以通过Java8流轻松完成。但这仍然会返回一个集合

例:

List matchingObjects=objects.stream。
过滤器(p->p.email().equals(“testemail”))。
collect(Collectors.toList());

但我知道它总是有一个独特的对象。我们可以做些什么来代替收集器。toList,这样我就可以直接得到实际的对象,而不是得到对象列表

尝试使用
findFirst
findAny
而不是使用收集器

Optional<Person> matchingObject = objects.stream().
    filter(p -> p.email().equals("testemail")).
    findFirst();
不过要小心
get
如果不存在值,则抛出
NoTouchElementException
。因此,强烈建议您首先确保值存在(使用
isPresent
或更好的方法,使用
ifPresent
map
orElse
可选
类中的任何其他选项)

如果您同意
null
引用,如果没有这样的人,那么:

Person person = matchingObject.orElse(null);
如果可能的话,我会尽量避免使用
null
参考路径。可选类中的其他替代方法(
ifPresent
map
等)可以解决许多用例。我发现自己在使用
orElse(null)
时,只有在某些情况下,我的现有代码设计为接受
null
引用


Optionals还有其他有用的方法。请看。

Guava API提供了一个收集器,它获取一个只包含一个元素的流,然后返回该元素

如果流由两个或多个元素组成,则返回的收集器抛出
IllegalArgumentException
,如果流为空,则抛出
NoTouchElementException

有关用法,请参阅以下代码:

import static com.google.common.collect.MoreCollectors.onlyElement;

Person matchingPerson = objects.stream
                        .filter(p -> p.email().equals("testemail"))
                        .collect(onlyElement());
findAny
orElse
通过使用和:

停止查找事件

findAny

可选findAny()

返回描述流的某个元素的可选值,如果流为空,则返回空可选值。 这是一种短路终端操作。 此操作的行为明显不确定;可以自由选择流中的任何元素。这是为了在并行操作中实现最大性能;代价是对同一个源的多次调用可能不会返回相同的结果。(如果需要稳定的结果,请改用findFirst()


谢谢虽然我建议尽可能不要使用orElse(null),但这很有帮助。这里的p是什么?流上的
filter
方法接受应用于每个流元素的lambda表达式
p
是lambda表达式的参数。由于
对象
的类型为
列表
p
在这种情况下是
Person person = matchingObject.orElse(null);
import static com.google.common.collect.MoreCollectors.onlyElement;

Person matchingPerson = objects.stream
                        .filter(p -> p.email().equals("testemail"))
                        .collect(onlyElement());
Person matchingObject = objects.stream().
filter(p -> p.email().equals("testemail")).
findAny().orElse(null);