我想检查一个适配器类的值,该类是设备类中的嵌套对象,如下所示:
@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;
}
如果为空,请为字段设置默认值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")))));
}
看起来,它可以工作,但IntelliJ抱怨二传手部分无效:
d.setAdapter(Optional.of(new Adapter("DDD")))
带有一条消息:
orElse Adapter in Optional cannot be applied to (void)
这里出现了一个问题,在这种情况下是否可以将 void 类型强制转换为 Optional 类型,以便这些类型彼此兼容或以不同的方式设置默认名称。
我注意到这里有几个问题。
- 您通过拥有
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"));
}
}
}
}
一个花哨的版本将是
device.flatMap(Device::getSocket).ifPresent(socket -> {
if (socket.getAdapter().isEmpty()) {
socket.setAdapter(Optional.of(new Adapter("DDD")));
}
});
是否可以将花哨版本的结果包装到 Adapter 类?
是的,但我不是这些事情的支持者。
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));
}