Java BinaryOperator Functional Interface Tutorial

Overview

Java BinaryOperator is a functional interface extending BiFunction. As you may recall, BiFunction has one abstract method called apply that accepts two arguments and returns a result.

A BinaryOperator is a special case of a BiFuncion where the types of the arguments and the return value are the same.

Thus, this is the signature of the apply function:

public interface BinaryOperator<T> extends BiFunction<T,T,T> {
 T apply(T t, T u); 
}

Why creating BinaryOperator?

You might ask why you need BinaryOperator when you can use BiFunction? The reason is it’s useful in cases where you want to perform binary operations with consistent input and output types, such as addition, multiplication, or other mathematical operations. It simplifies code and enhances type safety.

BinaryOperator Example

Let’s consider some examples using BinaryOperator:

    public static void main(String[] args) {
        BinaryOperator<Integer> sum = Integer::sum;
        BinaryOperator<Double> multiple = (a, b) -> a * b;
        BinaryOperator<Double> divide = (a, b) -> a / b;
        BinaryOperator<Integer> subtract = (a, b) -> a - b;
        
        System.out.println(sum.apply(1, 2));
        System.out.println(multiple.apply(1.0, 2.0));
        System.out.println(divide.apply(1.0, 2.0));
        System.out.println(subtract.apply(1, 2));

    }

The code above would produce the following result:

Using BinaryOperator for arithmetic operations

BinaryOperator statics methods

If you take a look at the source code, you’ll find that there are two static methods in BinaryOperator named minBy and maxBy.

These methods take a comparator and return a BinaryOperator.

Let’s consider the following example:

record Gun(String name, double damage, int ammo, float range) {
}

    public static void main(String[] args) {
        var ak47 = new Gun("AK-47", 10, 30, 100);
        var ma41 = new Gun("M4A1", 15, 30, 200);

        var rangeComparator = BinaryOperator.maxBy(Comparator.comparingDouble(Gun::range));
        var damageComparator = BinaryOperator.maxBy(Comparator.comparingDouble(Gun::damage));
        var ammoComparator = BinaryOperator.maxBy(Comparator.comparingInt(Gun::ammo));

        System.out.println("Best range: " + rangeComparator.apply(ak47, ma41));
        System.out.println("Best damage: " + damageComparator.apply(ak47, ma41));
        System.out.println("Best ammo: " + ammoComparator.apply(ak47, ma41));


    }

In the code above, I created a record called Gun that represents fictional specs of two of the most famous guns: AK47 and M4A1. Then, I created three comparators to compare the two guns across different specs.

Running the code above would produce the following result:

Using BinaryOperator static methods

Conclusion

This post showed you what is a BinaryOperator, and when is it a good fit. It also explored the usage of the two static methods maxBy and minBy.

Leave a Comment