使用 setter in 或 Else 子句为可选嵌套对象设置默认值
Set default value for optional nested object with setter in orElse clasue
我想检查适配器 class 的值,它是设备 class 中的嵌套对象,如下所示:
@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 抱怨 setter 部分无效:
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")));
}
});
is it possible to wrap the result from fancy version to the Adapter class?
是的,但我不支持这样的事情。
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));
}
我想检查适配器 class 的值,它是设备 class 中的嵌套对象,如下所示:
@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 抱怨 setter 部分无效:
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")));
}
});
is it possible to wrap the result from fancy version to the Adapter class?
是的,但我不支持这样的事情。
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));
}