マーティン:
私は次のようになり、デバイスクラスのネストされたオブジェクトであるアダプタクラスの値をチェックしたいです:
@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型をキャストするか、別の方法でデフォルトの名前を設定することが可能であるかどうかを生じます。
アンドリューTobilko:
私はここでの問題のカップルが気づきました。
- あなたは誤用
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")));
}
});
それは、アダプタクラスに空想のバージョンからの結果をラップすることは可能でしょうか?
はい、私はそのようなことのサポーターはないです。
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));
}