如果 stream().filter 为空

if stream().filter is empty

我想知道如果过滤器没有找到值并找到它,如何从流中执行代码,示例代码:

 @Transactional
public void change(ClassName dep){
    // code
    dep.getFoo()
            .stream()
            .filter(f -> f.getName().equals(doo.getName))
            
}

如果过滤器有值则:

user.setFoo(f);

如果过滤器中没有值则:

Foo foo = new Foo();
foo.setName("Exp");
user.setFoo(foo);

试试下一个例子:

Foo foo = new Foo();
foo.setName("Exp");


user.setFoo(dep.getFoo()
            .stream()
            .filter(f -> f.getName().equals(doo.getName))
            .findFirst().orElse(foo);

因为过滤器可以return超过一个对象,你应该限制在一个对象上。如果可选为空,findFirst 将 return 类型为 Optional 的对象,而 orElse 将 return foo。在其他情况下,您将成立 foo.

我建议为 Foo 创建一个接受 name 的构造函数。

然后您可以使用默认值 Optional:

提取名称
Foo foo = dep.getFoo()
        .stream()
        .filter(f -> f.getName().equals(doo.getName))
        .findAny().orElse(new Foo("Exp"));
user.setFoo(foo);

正如 Holger 巧妙地注意到的那样,如果 Optional 不为空,使用 orElseGet 将避免执行 Supplier(如果计算复杂或出现副作用则有益):

Foo foo = dep.getFoo()
        .stream()
        .filter(f -> f.getName().equals(doo.getName))
        .findAny().orElseGet(() -> new Foo("Exp"));
user.setFoo(foo);

因为 java 11 你可以使用 ifPresentOrElse:

dep.getFoo()
        .stream()
        .filter(f -> f.getName().equals(doo.getName))
        .findAny()
        .ifPresentOrElse(user::setFoo, () -> user.setFoo(new Foo("Exp")));

P.S.: 如果你不能创建构造器,你可以只创建提供它的方法并在上面的片段中使用它:

public static Foo defaultFoo() {
    Foo foo = new Foo();
    foo.setName("Exp");
    return foo;
}