2015-10-22 9 views
7

Ich versuche mich mit Lambda-Funktionen vertraut zu machen. Zunächst habe ich beschlossen, eine handliche Klasse namens TernaryOperator zu schreiben. Also, die Frage ist, ob ich die Ideologie richtig verstanden habe oder etwas vermisse, wie es anders gemacht werden sollte?Ist dies eine ordnungsgemäße Verwendung der Funktionsschnittstelle?

public class TernaryOperator<T, U> implements Function<T, U> { 

    private final Function<T, U> f; 

    public TernaryOperator(Predicate<? super T> condition, 
          Function<? super T, ? extends U> ifTrue, 
          Function<? super T, ? extends U> ifFalse) { 
     this.f = t -> condition.test(t) ? ifTrue.apply(t) : ifFalse.apply(t); 
    } 

    @Override 
    public U apply(T t) { 
     return f.apply(t); 
    } 
} 

Ich sehe Verwendung dieser Klasse wie folgt:

Predicate<Object> condition = Objects::isNull; 
Function<Object, Integer> ifTrue = obj -> 0; 
Function<CharSequence, Integer> ifFalse = CharSequence::length; 
Function<String, Integer> safeStringLength = new TernaryOperator<>(condition, ifTrue, ifFalse); 

Und jetzt kann ich eine Länge jeder Zeichenfolge berechnen, auch wenn es eine Null mit diesem oneliner ist.

Also, wenn Sie irgendwelche Ideen haben, wie man besser schreiben TernaryOperator oder wenn Sie denken, dass es nutzlos ist, bitte sagen Sie mir.

+3

Ihr Code ist völlig in Ordnung. – Jesper

+3

Dies ist besser geeignet für http://codereview.stackexchange.com/ –

Antwort

6

Keine Notwendigkeit, die Function Schnittstelle zu implementieren. Es ist besser, statische Methode in geeigneter Klasse zu schreiben statt:

public static <T, U> Function<T, U> ternary(Predicate<? super T> condition, 
         Function<? super T, ? extends U> ifTrue, 
         Function<? super T, ? extends U> ifFalse) { 
    return t -> condition.test(t) ? ifTrue.apply(t) : ifFalse.apply(t); 
} 

Und verwenden Sie wie folgt aus:

Function<String, Integer> safeStringLength = MyClass.ternary(condition, ifTrue, ifFalse); 

Sehen Sie sich auch import static für Ihre Utility-Klasse verwenden und einfach ternary(condition, ifTrue, ifFalse) schreiben.

Wahrscheinlich könnte eine solche Methode in einigen Situationen nützlich sein. Vor allem, wenn Sie Methodenverweise verwenden können. Zum Beispiel:

Stream.of(strings).map(ternary(String::isEmpty, x -> "none", String::trim))... 
+3

Aber fragen Sie sich, ob 'ternär (String :: isEmpty, x -> "none", String :: trim)' ist wirklich besser als der Ausdruck 's -> s.isEmpty()? "keine": s.trim() '... – Holger

Verwandte Themen