I have a use case, where I have nested classes and an object of the top class. I want to get a value which is at the Nth level. I'm using getters repetitively to achieve this to avoid NPE. Sample code (assuming getters are there)
class A {
String a1;
String getA1() {
return a1;
}
}
class B {
A a;
A getA() {
return a;
}
}
class C {
B b;
B getB() {
return b;
}
}
class D {
C c;
C getC() {
return c;
}
}
If I have an object d
of class D
, and want to get the String a1
of A
, what I'm doing is following:
String getAValue(D d) {
String aValue = null;
if(d != null && d.getC() != null && d.getC().getB() != null && d.getC().getB().getA() != null) {
aValue = d.getC().getB().getA().getA1();
}
return aValue;
}
This repetitive a is looking really ugly. How do I avoid it by using java8 Optional?
EDIT: I can't modify the above classes. Assume this d object is returned to me as a service call. I'm exposed to these getters only.
Use Optional
with a series of map()
calls for a nice one-liner:
String getAValue(D d) {
return Optional.ofNullable(d)
.map(D::getC).map(C::getB).map(B::getA).map(A::getA1).orElse(null);
}
If anything is null
along the chain, including d
itself, the orElse()
will execute.
Wrap each nested class in an Optional:
Class A {
String a1;
}
Class B {
Optional<A> a;
}
Class C {
Optional<B> b;
}
Class D {
Optional<C> c;
}
Then use flatMap and map to operate on these optional values:
String a1 = d.flatMap(D::getC) // flatMap operates on Optional
.flatMap(C::getB) // flatMap also returns an Optional
.flatMap(B::getA) // that's why you can keep calling .flatMap()
.map(A::getA1) // unwrap the value of a1, if any
.orElse("Something went wrong.") // in case anything fails
You might want to check out the concept of Monads. And if you're feeling adventurous, Scala is too distant from Java.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With