2015-10-22 12 views
7

Próbuję poznać funkcje lambda. Na początek postanowiłem napisać przydatną klasę o nazwie TernaryOperator. Pytanie brzmi: czy ideologia jest właściwa, czy też brakuje mi czegoś, co należy zrobić w inny sposób?Czy to właściwe korzystanie z interfejsu funkcji?

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

widzę wykorzystanie tej klasy tak:

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

A teraz mogę obliczyć długość dowolny ciąg nawet jeśli jest zerowy z tym oneliner.

Tak więc, jeśli masz jakieś pomysły, jak pisać lepiej TernaryOperator lub jeśli uważasz, że jest bezużyteczny, proszę powiedz mi.

+3

Twój kod jest całkowicie w porządku. – Jesper

+3

To jest lepiej dostosowane do http://codereview.stackexchange.com/ –

Odpowiedz

6

Nie trzeba implementować interfejsu Function. Lepiej napisać statycznej metody w jakiejś odpowiedniej klasy zamiast:

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

I używać tak:

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

również rozważyć użycie import static dla swojej klasie użytkowej i pisać po prostu ternary(condition, ifTrue, ifFalse).

Prawdopodobnie taka metoda może być przydatna w niektórych sytuacjach. Zwłaszcza, gdy można korzystać z referencji metod. Na przykład:

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

Ale zadaj sobie pytanie, czy 'ternary (String :: isEmpty, x ->" none ", String :: trim)' jest naprawdę lepsze niż wyrażenie 's -> s.isEmpty()? "none": s.trim() '... – Holger

Powiązane problemy