有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java映射到对象而不是另一个对象的现有方法可选<>吗?

我熟悉Optional.map(mapper),它将可选对象映射到其他对象。因此,如果我想用可选的Foo和非可选的Bar做一些事情,我可以做:

Optional<Foo> foobar = foo.map(foo -> foo.addBar(bar))

这有点像:

Optional<Foo> foobar = foo.isPresent() ? Optional.of(foo.get().add(bar)) : Optional.empty();

但我看到了一种反复出现的模式,bar是可选的。我要复制的功能如下所示:

Foo foobar = bar.isPresent() ? foo.add(bar.get()) : foo;

换句话说,如果其他事物存在,让我用它来做一些关于我现有事物的事情;否则,就把我现有的东西还给我

我可以想象自己制作Optionals.doIfOtherPresent(T object, Optional<U> optional, BiFunction<? super T, ? super U, ? extends T> fn)。我会这样使用它:

Foo foobar = doIfOtherPresent(foo, bar, foo::add);

Java库中已经有这样的东西了吗


共 (4) 个答案

  1. # 1 楼答案

    我认为从Optional<Bar>开始的其他答案对于很多情况都很好。如果在某个阶段有条件地需要foo.addBar在涉及Foo的较长方法链中,该方法也可以适用于那里(尚未测试):

        Optional<Foo> foobar = foo.map(foo -> bar.map(bar -> foo.addBar(bar)));
    
  2. # 2 楼答案

    你要找的是Optional.flatMap()

    以下构造:

    Foo result = optionalBar.isPresent() ? optionalFooFromBar( optionalBar.get() ) : foo;

    可以改写为:

    Foo result = optionalBar.flatMap( bar -> optionalFooFromBar( bar ) ).orElse( foo );

    请注意,您保存了整整两个字符

  3. # 3 楼答案

    使用bar而不是foo似乎可以简化它:

    Foo foobar = bar
             .map(b -> foo.map(f -> f.add(b)))
             .orElse(foo)
             .orElse(null); // if foo is not present
    

    bar.map(b -> foo.map(f -> f.add(b)))如果bar存在,则返回Optional<Optional<Foo>>即“存在”

    如果bar不存在,则.orElse(foo)还原为原始Optional<Foo>(否则返回foo.map(f -> f.add(b))

  4. # 4 楼答案

    根据您提供的示例,如果bar存在,您似乎希望应用操作foo.add,否则返回foo

    Foo foobar = bar.isPresent() ? foo.add(bar.get()) : foo;
    

    因此,我想说它太短了,不值得为它创建一个实用的方法

    Foo foobar = optBar.map(f::add).orElse(f); // map to Foo if bar is present else return `f`
    
    • 如果optBar有一个当前状态,我们应用map操作orElse返回映射的值
    • 如果optBar有一个缺席状态,orElse方法返回提供的默认值f

    另一件事,您是首先以Optional<Bar>的形式获得结果,还是手动将Bar包装成可选的?如果是后者,我可能只会使用一个简单的if语句,这将是理想的解决方案,即

    Foo foo = new Foo();
    if(bar != null) foo = foo.add(bar);