2016-07-26 5 views
3

Ich spiele mit Anwendungen einer FunctionalInterface. Ich habe überall mehrere Variationen des folgenden Codes gesehen:Java - lambda infer Typ

int i = str != null ? Integer.parseInt() : null; 

ich für das folgende Verhalten freu:

int i = Optional.of(str).ifPresent(Integer::parseInt); 

Aber ifPresent akzeptiert nur eine Supplier und Optional kann nicht verlängert werden.

Ich habe folgende FunctionalInterface erstellt:

@FunctionalInterface 
interface Do<A, B> { 

    default B ifNotNull(A a) { 
     return Optional.of(a).isPresent() ? perform(a) : null; 
    } 

    B perform(A a); 
} 

Dies ermöglicht es mir, dies zu tun:

Integer i = ((Do<String, Integer>) Integer::parseInt).ifNotNull(str); 

Man kann mehr Standardmethoden hinzufügen Dinge wie

LocalDateTime date = (Do<String, LocalDateTime> MyDateUtils::toDate).ifValidDate(dateStr); 

Und zu tun es liest schön Do [my function] and return [function return value] if [my condition] holds true for [my input], otherwise null.

Warum kann der Compiler ableiten, die Typen von A (String zu ifNotNull bestanden) und B (Integer zurück von parseInt), wenn ich wie folgt vorgehen:

Integer i = ((Do) Integer::parseInt).ifNotNull(str); 

Daraus ergibt sich:

inkompatible Typen: ungültige Methodenreferenz

Antwort

9

Für Ihre ursprüngliche Problem Optional stark genug ist, mit nullable Werte

Integer i = Optional.ofNullable(str).map(Integer::parseInt).orElse(null); 

Für aktuelles Beispiel zu behandeln wäre es wie

Date date = Optional.ofNullable(str).filter(MyDateUtils::isValidDate).map(MyDateUtils::toDate).orElse(null); 
schauen

In Bezug auf Art Fehler

Integer i = ((Do<String, Integer>) Integer::parseInt).ifNotNull(str); 

generic Angeben Argumente für Do Schnittstelle löst ein Problem. Die Sache ist, dass nur Do ohne angegebenen Typ Argumente Do<Object, Object> und Integer::parseInt nicht diese Schnittstelle entspricht.

+0

Ah toll, mir war die 'map' Funktionalität von' Optional' nicht bekannt. Vielen Dank! – Ian2thedv

+0

Froh, dass geholfen hat. Sehen Sie sich 'Optional # flatMap' an, es ist die universellste von' Optional' Methoden –