Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of Unaryoperator and Binaryoperator when I have Function in Java 8

Tags:

java

java-8

In Java 8, there are many functional interfaces provided such as UnaryOperator, BinaryOperator and Function etc.

The Code,

UnaryOperator<Integer> uOp = (Integer i) -> i * 10;
BinaryOperator<Integer> bOp = (Integer i1, Integer i2) -> i1 * i2 * 10;

can always be written using Function as below,

Function<Integer, Integer> f1 = (Integer i) -> i * 10;
BiFunction<Integer, Integer, Integer> f2 = (Integer i1, Integer i2) -> i1 * i2 * 10;

So, whats the use of these operator interfaces ? Are they achieving anything different than what can be achieved using Function ?

like image 546
CourseTriangle Avatar asked Jan 02 '23 08:01

CourseTriangle


2 Answers

Functional interfaces should be specialised as possible.

Having

Function<Integer, Integer> f1 = (Integer i) -> i * 10;

Instead of:

UnaryOperator<Integer> uop1 = (Integer i) -> i * 10;

is actually a code smell (there is also Sonar Rule squid:S4276 for this).

The simple reason for this is that these interfaces were created to avoid passing unnecessary type parameters n times while you have only one.

public interface UnaryOperator<T> extends Function<T, T>

So writing a Function<T, T> is just longer and unnecessary.

Talking about other interfaces like: IntConsumer vs. Consumer<Integer> or DoubleToIntFunction vs. Function<Double, Integer> where the second option may lead to unnecessary auto-boxing and may downgrade performance.

So that's why using more specific and appropriate interface makes your code look cleaner and keeps you away from surprises.

like image 74
J-Alex Avatar answered Feb 20 '23 04:02

J-Alex


They are here for your convenience. You can spare writing BiFunction<Integer, Integer, Integer> and just write/use a BinaryOperator<Integer> instead. An additional benefit: you can ensure that the function that is given to you accepts 1 or two parameters of the same type and return exactly that type without much more writing.

Additionally due to the nature of BinaryOperator<T> it makes more sense to put something like minBy and maxBy there, which doesn't really make so much sense to put into a BiFunction<T, U, R>. As the given parameters there are of same type and the return type is ensured also to be the same, a comparator can be easily applied... very convenient.

like image 20
Roland Avatar answered Feb 20 '23 04:02

Roland