I am trying to get familiar with lambda functions. To start with I decided to write a handy class called TernaryOperator
. So, the question is did I get the ideology right or am I missing something as it should be done in a different way?
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);
}
}
I see usage of this class like this:
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);
And now I can calculate a length of any string even if it is a null with this oneliner.
So, if you have any ideas how to write better TernaryOperator
or if you think that it is useless, please tell me.
A functional interface is an interface that contains only one abstract method. They can have only one functionality to exhibit. From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods.
Further, due to the fact that we can use functional interfaces as target types for lambda expressions & methods references, this would be useful when: passing a comparator to a sort method e.g. List. sort , Stream. sorted , Collections.
The Function Interface is a part of the java. util. function package which has been introduced since Java 8, to implement functional programming in Java. It represents a function which takes in one argument and produces a result.
The correct answer is A.A functional interface must declare one abstract method. Since interface B only declares a static method and inherits a default one, it won't compile, not even by adding another default method or by having the @FunctionalInterface annotation.
No need to implement the Function
interface. It's better to write static method in some appropriate class instead:
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);
}
And use like this:
Function<String, Integer> safeStringLength = MyClass.ternary(condition, ifTrue, ifFalse);
Also consider using import static
for your utility class and write simply ternary(condition, ifTrue, ifFalse)
.
Probably such method could be useful in some situations. Especially when you can use method references. For example:
Stream.of(strings).map(ternary(String::isEmpty, x -> "none", String::trim))...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With