Java LongBinaryOperator 接口
最后修改时间:2025 年 4 月 16 日
java.util.function.LongBinaryOperator 接口表示对两个 long 值的操作,产生一个 long 结果。它是一个函数式接口,只有一个抽象方法 applyAsLong。此接口专门用于原始 long 类型,以避免装箱开销。
LongBinaryOperator 是 Java 8 中添加的 Java 函数式编程实用程序的一部分。它对于数学运算和规约(reduction)非常有用,在原始类型上进行性能优化时很重要。该接口没有默认方法或静态方法。
LongBinaryOperator 接口概述
LongBinaryOperator 接口包含一个必须实现的方法。该方法接受两个 long 参数并返回一个 long 值。这使其成为对原始 long 类型进行算术运算的理想选择。
@FunctionalInterface
public interface LongBinaryOperator {
long applyAsLong(long left, long right);
}
上面的代码显示了 LongBinaryOperator 的简单结构。它使用 @FunctionalInterface 注解来指示其单一抽象方法。该接口通过使用原始类型来避免对象创建开销。
LongBinaryOperator 的基本用法
使用 LongBinaryOperator 的最简单方法是使用 lambda 表达式。我们定义如何将两个 long 值组合成一个结果。该示例显示了基本的算术运算。
package com.zetcode;
import java.util.function.LongBinaryOperator;
public class Main {
public static void main(String[] args) {
// Define addition operator
LongBinaryOperator add = (a, b) -> a + b;
// Define multiplication operator
LongBinaryOperator multiply = (a, b) -> a * b;
System.out.println("10 + 20 = " + add.applyAsLong(10, 20));
System.out.println("5 * 7 = " + multiply.applyAsLong(5, 7));
// Using method reference for max operation
LongBinaryOperator max = Math::max;
System.out.println("Max of 15 and 25: " + max.applyAsLong(15, 25));
}
}
此示例演示了使用 lambda 表达式的基本 LongBinaryOperator 用法。我们创建了加法和乘法的运算符。方法引用展示了如何使用与接口兼容的现有方法。打印结果。
使用 LongBinaryOperator 进行 reduce 操作
LongBinaryOperator 常用在原始 long 类型的流上的 reduce 操作中。这允许有效的聚合,而无需装箱开销。该示例对 LongStream 中的数字求和。
package com.zetcode;
import java.util.stream.LongStream;
import java.util.function.LongBinaryOperator;
public class Main {
public static void main(String[] args) {
LongStream numbers = LongStream.of(1, 2, 3, 4, 5);
// Sum reduction using LongBinaryOperator
long sum = numbers.reduce(0, (a, b) -> a + b);
System.out.println("Sum: " + sum);
// Alternative with method reference
LongStream numbers2 = LongStream.of(10, 20, 30);
long sum2 = numbers2.reduce(0, Long::sum);
System.out.println("Sum2: " + sum2);
// Product reduction
LongStream factors = LongStream.of(2, 3, 4);
long product = factors.reduce(1, (a, b) -> a * b);
System.out.println("Product: " + product);
}
}
此示例展示了 LongBinaryOperator 在流规约中的应用。我们使用 lambda 表达式和方法引用对数字求和。乘积计算演示了另一种常见的规约模式。所有操作都直接使用原始 long 类型。
自定义数学运算
我们可以使用 LongBinaryOperator 实现自定义数学运算。当标准运算符无法满足需求时,这非常有用。该示例展示了幂运算和最大公约数 (GCD) 的计算。
package com.zetcode;
import java.util.function.LongBinaryOperator;
public class Main {
public static void main(String[] args) {
// Power operation
LongBinaryOperator power = (base, exponent) -> {
long result = 1;
for (long i = 0; i < exponent; i++) {
result *= base;
}
return result;
};
System.out.println("2^5 = " + power.applyAsLong(2, 5));
// GCD operation using Euclidean algorithm
LongBinaryOperator gcd = (a, b) -> {
while (b != 0) {
long temp = b;
b = a % b;
a = temp;
}
return a;
};
System.out.println("GCD of 56 and 42: " + gcd.applyAsLong(56, 42));
}
}
此示例实现了自定义数学运算。幂运算符通过迭代计算指数。GCD 运算符使用欧几里德算法。两者都展示了如何封装复杂的运算。
与其他函数式接口组合
LongBinaryOperator 可以与其他函数式接口结合使用,以获得更复杂的行为。该示例展示了在操作之前进行过滤以及链式操作。
package com.zetcode;
import java.util.function.LongBinaryOperator;
import java.util.function.LongPredicate;
public class Main {
public static void main(String[] args) {
// Only operate if both numbers are even
LongBinaryOperator conditionalAdd = (a, b) -> {
LongPredicate isEven = n -> n % 2 == 0;
return isEven.test(a) && isEven.test(b) ? a + b : 0;
};
System.out.println("Conditional add (4,6): " +
conditionalAdd.applyAsLong(4, 6));
System.out.println("Conditional add (3,8): " +
conditionalAdd.applyAsLong(3, 8));
// Chaining operations
LongBinaryOperator addThenDouble = (a, b) -> (a + b) * 2;
System.out.println("Add then double (3,4): " +
addThenDouble.applyAsLong(3, 4));
}
}
此示例将 LongBinaryOperator 与 LongPredicate 结合用于条件操作。我们还展示了如何在单个 lambda 中链接操作。这展示了 Java 中函数组合的灵活性。
在并行流中使用
LongBinaryOperator 在并行流中特别有用,其中操作必须是可结合的,才能获得正确的结果。该示例展示了使用自定义运算符的并行规约。
package com.zetcode;
import java.util.stream.LongStream;
import java.util.function.LongBinaryOperator;
public class Main {
public static void main(String[] args) {
// Custom associative operation (a + b)^2
LongBinaryOperator sumOfSquares = (a, b) -> (a + b) * (a + b);
long result = LongStream.rangeClosed(1, 10)
.parallel()
.reduce(0, sumOfSquares);
System.out.println("Parallel reduction result: " + result);
// Verification with sequential stream
long seqResult = LongStream.rangeClosed(1, 10)
.reduce(0, sumOfSquares);
System.out.println("Sequential result: " + seqResult);
}
}
此示例演示了使用自定义可结合操作的并行流规约。运算符必须是可结合的才能在并行中正确工作。我们验证了并行和顺序执行的结果匹配。
性能比较
与基于对象的替代方案相比,使用 LongBinaryOperator 处理原始 long 类型可以提供显著的性能优势。该示例比较了原始类型和基于对象的规约。
package com.zetcode;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import java.util.function.LongBinaryOperator;
import java.util.function.BinaryOperator;
public class Main {
public static void main(String[] args) {
final int SIZE = 10_000_000;
// Primitive long stream with LongBinaryOperator
long start = System.currentTimeMillis();
long sum = LongStream.rangeClosed(1, SIZE)
.reduce(0, (a, b) -> a + b);
long primitiveTime = System.currentTimeMillis() - start;
// Object stream with BinaryOperator
start = System.currentTimeMillis();
Long sumObj = Stream.iterate(1L, n -> n + 1)
.limit(SIZE)
.reduce(0L, (a, b) -> a + b);
long objectTime = System.currentTimeMillis() - start;
System.out.println("Primitive sum: " + sum + " in " +
primitiveTime + "ms");
System.out.println("Object sum: " + sumObj + " in " +
objectTime + "ms");
}
}
此示例比较了原始 long 操作和装箱 Long 操作之间的性能。使用 LongBinaryOperator 的原始类型版本通常更快,因为它避免了装箱开销。打印结果和时间。
来源
在本文中,我们涵盖了 Java LongBinaryOperator 接口的基本使用模式。理解这些概念对于在现代 Java 应用程序中进行高效的数值处理至关重要。
作者
列出所有Java教程。