2015-09-16 15 views
5

私はネストされたクラスとトップクラスのオブジェクトを持つユースケースを持っています。私はN番目のレベルにある値を取得したい。私はNPEを避けるためにゲッターを繰り返し使用しています。サンプルコード(仮定ゲッターがある)繰り返しのget文をJava 8に置き換えるオプション

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を持っている、とAString a1を取得したい場合は、私がやっていることは以下の通りです:

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を使用して回避するにはどうすればいいですか?

編集:私は上記のクラスを変更することはできません。このdオブジェクトがサービスコールとして私に返されたとします。私はこれらのゲッタにのみさらされています。

答えて

2

ラップオプションの各ネストされたクラス:

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

その後flatMapを使用して、これらのオプションの値を操作するためにマップ:

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。素敵なワンライナー用map()一連の呼び出しと

+0

'getC'がnullableの' C'を返す場合、 'map(D :: getC)'も動作します。 – ZhongYu

6

使用Optional

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

何がd含むチェーンに沿ってnull、自身である場合は、orElse()が実行されます。

+1

それはうまくいった。ありがとうございました! :) – AKB

関連する問題