Java 使用orElse clasue中的setter设置可选嵌套对象的默认值

Java 使用orElse clasue中的setter设置可选嵌套对象的默认值,java,functional-programming,java-stream,java-11,Java,Functional Programming,Java Stream,Java 11,我想检查适配器类的值,它是设备类中的嵌套对象,如下所示: @Setter @Getter public class Device { private Optional<Socket> socket; } @Setter @Getter public class Socket { private Optional<Adapter> adapter = Optional.empty(); } @Setter @Getter @AllArgsConstruc

我想检查适配器类的值,它是设备类中的嵌套对象,如下所示:

@Setter
@Getter
public class Device {
    private Optional<Socket> socket;
}
@Setter
@Getter
public class Socket {
    private Optional<Adapter> adapter = Optional.empty();
}
@Setter
@Getter
@AllArgsConstructor
public class Adapter {
    public String name;
}
public static Optional<Adapter> checkAdapterNameOrSetDefaultValue(Optional<Device> device) {
return device
        .flatMap(Device::getSocket)
        .ifPresent(d -> d.getAdapter().orElse(d.setAdapter(Optional.of(new Adapter("DDD")))));
}
如果为空,则为字段
name
设置默认值

我的方法如下所示:

@Setter
@Getter
public class Device {
    private Optional<Socket> socket;
}
@Setter
@Getter
public class Socket {
    private Optional<Adapter> adapter = Optional.empty();
}
@Setter
@Getter
@AllArgsConstructor
public class Adapter {
    public String name;
}
public static Optional<Adapter> checkAdapterNameOrSetDefaultValue(Optional<Device> device) {
return device
        .flatMap(Device::getSocket)
        .ifPresent(d -> d.getAdapter().orElse(d.setAdapter(Optional.of(new Adapter("DDD")))));
}
带着一条信息:

orElse Adapter in Optional cannot be applied to (void)

这里出现的问题是,在这种情况下,是否可以将void类型强制转换为Optional,以使这些类型彼此兼容,或者以不同的方式设置默认名称。

我注意到这里有几个问题

  • 通过使用
    Optional
    字段,您误用了
    Optional
  • 通过将其作为方法参数传递,您误用了
    可选的
  • checkAdapterNameOrSetDefaultValue
    听起来像是一种
    void
    方法。
    check
    set
    都不表示返回值
  • 撇开这些不谈,这里有一个简单的方法来实现它

    public static void checkAdapterNameOrSetDefaultValue(Optional<Device> device) {
        if (device.isPresent()) {
            final Optional<Socket> optionalSocket = device.get().getSocket();
            if (optionalSocket.isPresent()) {
                final Socket socket = optionalSocket.get();
                if (socket.getAdapter().isEmpty()) {
                    socket.setAdapter(Optional.of(new Adapter("DDD"));
                }
            }
        }
    }
    

    是否可以将结果从高级版本包装到适配器类

    是的,但我不是这些事情的支持者

    public static Optional<Adapter> checkAdapterNameOrSetDefaultValue(Optional<Device> device) {
        final Adapter defaultAdapter = new Adapter("DDD");
    
        return Optional.of(device
                .flatMap(Device::getSocket)
                .map(d -> {
                    if (d.getAdapter().isEmpty()) {
                        d.setAdapter(Optional.of(defaultAdapter));
                        return defaultAdapter;
                    }
                    return d.getAdapter().get();
                })
                .orElseGet(() -> defaultAdapter));
    }
    
    public静态可选checkAdapterNameOrSetDefaultValue(可选设备){
    最终适配器defaultAdapter=新适配器(“DDD”);
    返回可选的.of(设备)
    .flatMap(设备::getSocket)
    .地图(d->{
    if(d.getAdapter().isEmpty()){
    d、 setAdapter(可选的。of(defaultAdapter));
    返回默认适配器;
    }
    返回d.getAdapter().get();
    })
    .orElseGet(()->defaultAdapter));
    }
    
    它不是IntelliJ,而是Java编译器本身
    orElse
    需要一个值(),而setter函数不返回任何内容,甚至不返回
    Void
    Void
    类和
    Void
    关键字是两个不同的东西)。相反,只需尝试将这个
    可选的.of(新适配器(“DDD”)
    传递到
    orElse
    。您的函数看起来有点奇怪。您正在获取设备的适配器,并且正在设置一个适配器,以防它为空-我认为这是一个意外的副作用。我建议你将这两件事分开,如果缺少一个适配器,那么设置一个新的适配器应该会更容易。@Sachithdickkwella我的话并不准确,我只是更喜欢演示一个简单的IntelliJ消息。我会检查你的建议。一切准备就绪:)。我知道这不是很好的做法,但我继承了代码的这一部分,我没有什么可说的。是否可以将
    高级版本的结果
    包装到适配器类中?我这样问是因为我在任何情况下都不能更改该方法的签名。事实上,它看起来像一个怪物,但工作非常完美。像往常一样,感谢您的快速响应。@andreTobilko如果存在像
    defaultAdapter
    这样的东西,那么最好将其设置在
    Socket
    本身中。好吧,也许他没有进入教室的权限。