用Java 8替换重复的get语句可选

时间:2015-09-16 03:39:38

标签: java optional

我有一个用例,我有嵌套类和顶级类的对象。我想得到一个在第N级的值。我正在重复使用吸气剂来实现这一点以避免NPE。示例代码(假设有吸气剂)

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;
    }
}

如果我有一个d类的对象D,并希望得到String a1 A,那么我正在做的是:

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;
}

这个重复的看起来真的很难看。如何使用java8 Optional?

来避免它 编辑:我不能修改上面的类。假设这个d对象作为服务调用返回给我。我只接触过这些吸气剂。

2 个答案:

答案 0 :(得分:6)

使用Optional进行一系列map()调用,以获得一个不错的单行代码:

String getAValue(D d) {
   return Optional.ofNullable(d)
       .map(D::getC).map(C::getB).map(B::getA).map(A::getA1).orElse(null);
}

如果链中的任何内容null,包括d本身,orElse()将会执行。

答案 1 :(得分:2)

将每个嵌套类包装在Optional:

Class A {
    String a1;
}
Class B {
    Optional<A> a;
}
Class C {
    Optional<B> b;
}
Class D {
    Optional<C> c;
}

然后使用flatMap和map来操作这些可选值:

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

您可能想查看Monads的概念。如果你有冒险精神,Scala is too distant from Java