Java BinaryOperator接口指南

通过使用Lambda表达式、方法引用和类型特定版本(如IntBinaryOperator),利用Java BinaryOperator接口进行函数式编程。
On this page

Java BinaryOperator接口指南

在Java中,BinaryOperator接口是函数式编程的强大工具。作为一个函数式接口,BinaryOperator表示对相同类型的两个操作数进行操作,产生相同类型的结果。在本文中,我们将探讨如何使用Java的BinaryOperator来实现更简洁和更具声明性的代码。

BinaryOperator接口是在Java 8中引入的,与lambda表达式和流API一起。它位于java.util.function包中,接受两个相同类型T的泛型参数。BinaryOperator扩展了BiFunction接口,但限制了参数类型和返回类型都必须相同。这使得BinaryOperator非常适合数学运算、规约以及基于比较器的查找最小/最大值等用例。

BinaryOperator接口提供的一些关键方法包括:

  • apply() - 对两个操作数应用lambda操作
  • minBy() - 基于比较器返回最小值
  • maxBy() - 基于比较器返回最大值

通过使用Java的BinaryOperator函数式接口,开发人员可以编写简洁而具有声明性的函数式代码。在本文的其余部分,我们将通过代码示例更深入地探讨BinaryOperator的用法。

BinaryOperator介绍

BinaryOperator接口属于java.util.function包。它接受两个类型为T的泛型参数,对它们进行操作,并返回类型为T的结果。

例如:

1BinaryOperator<Integer> add = (x, y) -> x + y;
2
3Integer result = add.apply(2, 3); //result is 5

BinaryOperator的主要特点包括:

与可以接受不同参数类型的BiFunction相比,BinaryOperator将类型限制为相同。这使得它非常适用于数学和归约操作。

BinaryOperator方法

BinaryOperator接口包含三个主要方法:

apply()

该抽象方法接受两个类型为T的参数,并产生一个类型为T的结果。Lambda表达式或方法引用实现apply()逻辑。

例如:

1BinaryOperator<String> concat = (str1, str2) -> str1 + str2;
2
3String result = concat.apply("Hello", "IToolkit"); //"HelloIToolkit"

minBy()

该静态方法接受一个Comparator,并返回一个BinaryOperator,根据Comparator定义返回两个值中的最小值。

例如:

1Comparator<Integer> cmp = (a, b) -> a.compareTo(b);
2
3BinaryOperator<Integer> min = BinaryOperator.minBy(cmp);
4
5Integer minVal = min.apply(5, 3); // 3

maxBy()

类似于minBy(),但返回一个BinaryOperator,根据传入的Comparator定义返回两个值中的最大值。

例如:

1Comparator<String> cmp = (a, b) -> b.length() - a.length();
2
3BinaryOperator<String> max = BinaryOperator.maxBy(cmp);
4
5String maxStr = max.apply("Apple", "Banana"); // "Banana"

使用BinaryOperators

BinaryOperators有一些常见的用法:

使用Lambda表达式

1BinaryOperator<Long> addLongs = (x, y) -> x + y;
2
3long sum = addLongs.apply(5L, 10L); //15

使用方法引用

1BinaryOperator<String> concat = String::concat;
2
3String result = concat.apply("Hello ", "IToolkit!"); //"Hello IToolkit!"

作为参数传递

可以传递给高阶函数

1public static <T> T reduce(List<T> list, T identity, BinaryOperator<T> accumulator){
2  T result = identity;
3  for(T t : list){
4     result = accumulator.apply(result, t);
5  }
6  return result;
7}
8
9Integer sum = reduce(Arrays.asList(1, 2, 3), 0, Integer::sum);

类型特定的BinaryOperators

为了更好地处理原始类型,存在专门的BinaryOperator版本:

  • IntBinaryOperator
  • LongBinaryOperator
  • DoubleBinaryOperator

在对原始类型进行操作时,应使用这些版本,而不是装箱的BinaryOperators。

例如:

1IntBinaryOperator add = (x, y) -> x + y;
2int sum = add.applyAsInt(3, 5); // 8

BinaryOperator代码示例

以下是一些示例,演示了常见的用法:

基本用法

1// String concatenation
2BinaryOperator<String> concat = String::concat;
3String result = concat.apply("Hello ", "IToolkit!");
4
5// Numeric addition
6BinaryOperator<Integer> add = (x, y) -> x + y;
7int sum = add.apply(3, 5);

查找最小值/最大值

1// Find min length string
2Comparator<String> cmp = Comparator.comparingInt(String::length);
3BinaryOperator<String> min = BinaryOperator.minBy(cmp);
4String minStr = min.apply("Apple", "Banana");
5
6// Find max length string
7BinaryOperator<String> max = BinaryOperator.maxBy(cmp);
8String maxStr = max.apply("Apple", "Banana");

减少流

1Integer sum = list.stream()
2  .reduce(0, (a, b) -> a + b);
3
4// With method reference
5Integer sum = list.stream()
6  .reduce(0, Integer::sum);

原始类型

1IntBinaryOperator add = (x, y) -> x + y;
2int sum = add.applyAsInt(3, 5);
3
4LongBinaryOperator longAdd = (x, y) -> x + y;
5long longSum = longAdd.applyAsLong(10000, 20000);

何时使用BinaryOperator

在以下情况下,BinaryOperator非常有用:

  • 减少并行流 - 并发安全
  • 对相同类型进行数学运算
  • 基于自定义比较器查找最小/最大值
  • 对两个相同类型操作数进行任何通用的函数操作

它为这些对称二元操作提供了一个简单的函数接口。

结论

BinaryOperator接口是一个方便的函数接口,用于操作相同类型的两个值。它减少了匿名内部类的样板代码。

常见的用例包括减少集合、数学运算、基于自定义比较找到最小/最大值以及消除空检查。

通过在Java 8代码中与流和Lambda一起使用BinaryOperator,您可以编写非常简洁但易读的函数式代码。