2015-09-16 19 views
5

Mam przypadek użycia, w którym mam zagnieżdżone klasy i obiekt najwyższej klasy. Chcę uzyskać wartość, która jest na poziomie N-tym. Używam getters powtarzalnie, aby to osiągnąć, aby uniknąć NPE. Przykładowy kod (zakładając getters istnieją)Zamienianie powtarzających się instrukcji pobierania na Java 8 Opcjonalnie

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

Jeśli mam obiektu d klasy D i chcesz uzyskać String a1 z A, co robię jest następujący:

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

ten powtarzające się jest naprawdę brzydkie. Jak mogę tego uniknąć, używając java8 Opcjonalnie?

EDYCJA: Nie mogę zmodyfikować powyższych klas. Załóżmy, że ten obiekt d został mi zwrócony jako wezwanie serwisowe. Jestem wystawiony tylko na te działania.

Odpowiedz

2

Wrap każda klasa zagnieżdżona w opcjonalnym:

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

Następnie użyj flatMap i map do pracy na tych opcjonalnych wartości:

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 

Możesz chcieć sprawdzić koncepcję Monads. A jeśli masz ochotę na przygodę, Scala is too distant from Java.

+0

'map (D :: getC)' również działa, jeśli 'getC' zwraca nullable' C'. – ZhongYu

6

Zastosowanie Optional z serii map() połączeń za miły jedną wkładką:

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

Jeśli coś jest null wzdłuż łańcucha, w tym d sobie, orElse() wykona.

+1

To działało. Dziękuję Ci! :) – AKB

Powiązane problemy