Java ToDoubleBiFunction 接口
最后修改时间:2025 年 4 月 16 日
java.util.function.ToDoubleBiFunction
接口表示一个接受两个参数并产生 double 类型结果的函数。它是一个函数式接口,只有一个抽象方法 applyAsDouble
。
ToDoubleBiFunction
是 Java 8 中添加的 Java 函数式编程工具的一部分。它专门用于原始 double 类型的输出,以避免装箱开销。此接口对数值计算非常有用。
ToDoubleBiFunction 接口概述
ToDoubleBiFunction
接口包含一个抽象方法,该方法接受两个参数并返回一个 double 值。它使用两个泛型类型参数化,用于输入参数。
@FunctionalInterface public interface ToDoubleBiFunction<T, U> { double applyAsDouble(T t, U u); }
上面的代码展示了 ToDoubleBiFunction
的结构。它使用泛型,其中 T 和 U 是输入类型。该接口使用 @FunctionalInterface 注解,以表明其单抽象方法性质。
ToDoubleBiFunction 的基本用法
使用 ToDoubleBiFunction 的最简单方法是使用 lambda 表达式。我们定义如何处理两个输入以产生一个 double 结果。该示例计算产品价格。
package com.zetcode; import java.util.function.ToDoubleBiFunction; public class Main { public static void main(String[] args) { // Calculate total price (quantity * unitPrice) ToDoubleBiFunction<Integer, Double> calculateTotal = (quantity, unitPrice) -> quantity * unitPrice; double total1 = calculateTotal.applyAsDouble(5, 12.99); double total2 = calculateTotal.applyAsDouble(3, 8.50); System.out.println("Total 1: " + total1); System.out.println("Total 2: " + total2); } }
此示例演示了 ToDoubleBiFunction 的基本用法。lambda 表达式接受 Integer 数量和 Double 单价,并返回它们的乘积。通过直接使用原始 double,我们避免了装箱/拆箱开销。
计算欧几里得距离
ToDoubleBiFunction 非常适合需要两个输入的数学运算。此示例计算两个 2D 点之间的欧几里得距离。
package com.zetcode; import java.util.function.ToDoubleBiFunction; public class Main { public static void main(String[] args) { // Calculate distance between two points (x1,y1) and (x2,y2) ToDoubleBiFunction<Point, Point> distanceCalculator = (p1, p2) -> Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)); Point pointA = new Point(1, 2); Point pointB = new Point(4, 6); double distance = distanceCalculator.applyAsDouble(pointA, pointB); System.out.printf("Distance between points: %.2f%n", distance); } } class Point { double x, y; Point(double x, double y) { this.x = x; this.y = y; } }
此示例展示了 ToDoubleBiFunction 与自定义对象的使用。lambda 表达式使用标准公式计算距离。结果作为原始 double 返回,以便在数值运算中获得更好的性能。
加权平均计算
ToDoubleBiFunction 可以处理值的集合。此示例计算来自两个值和权重数组的加权平均值。
package com.zetcode; import java.util.function.ToDoubleBiFunction; public class Main { public static void main(String[] args) { // Calculate weighted average ToDoubleBiFunction<double[], double[]> weightedAverage = (values, weights) -> { if (values.length != weights.length) { throw new IllegalArgumentException("Arrays must be same length"); } double sum = 0; double weightSum = 0; for (int i = 0; i < values.length; i++) { sum += values[i] * weights[i]; weightSum += weights[i]; } return sum / weightSum; }; double[] scores = {90, 85, 78}; double[] weights = {0.3, 0.4, 0.3}; double average = weightedAverage.applyAsDouble(scores, weights); System.out.printf("Weighted average: %.2f%n", average); } }
此示例演示了 ToDoubleBiFunction 的复杂计算。lambda 表达式接受两个 double 数组并计算它们的加权平均值。输入验证确保在处理之前数组具有匹配的长度。
与集合一起使用
ToDoubleBiFunction 可以与 Java 集合很好地配合使用。此示例处理两个映射,以查找它们的值之间的相关性。
package com.zetcode; import java.util.Map; import java.util.function.ToDoubleBiFunction; public class Main { public static void main(String[] args) { // Calculate correlation between two maps' values ToDoubleBiFunction<Map<String, Double>, Map<String, Double>> correlation = (map1, map2) -> { double sumX = 0, sumY = 0, sumXY = 0; double sumX2 = 0, sumY2 = 0; int n = 0; for (String key : map1.keySet()) { if (map2.containsKey(key)) { double x = map1.get(key); double y = map2.get(key); sumX += x; sumY += y; sumXY += x * y; sumX2 += x * x; sumY2 += y * y; n++; } } if (n == 0) return 0; double numerator = sumXY - (sumX * sumY) / n; double denominator = Math.sqrt( (sumX2 - (sumX * sumX) / n) * (sumY2 - (sumY * sumY) / n); return numerator / denominator; }; Map<String, Double> testScores = Map.of( "Alice", 85.0, "Bob", 72.0, "Charlie", 90.0); Map<String, Double> studyHours = Map.of( "Alice", 12.5, "Bob", 8.0, "Charlie", 15.0); double corr = correlation.applyAsDouble(testScores, studyHours); System.out.printf("Correlation coefficient: %.2f%n", corr); } }
这个高级示例展示了 ToDoubleBiFunction 处理两个映射。它计算匹配值之间的皮尔逊相关系数。该实现使用原始 double 进行所有数学运算,以提高效率。
与其他函数式接口组合
ToDoubleBiFunction 可以与其他函数式接口组合使用。此示例展示了与 Function 组合以进行更复杂的转换。
package com.zetcode; import java.util.function.Function; import java.util.function.ToDoubleBiFunction; public class Main { public static void main(String[] args) { // Convert string pairs to similarity score (0-1) ToDoubleBiFunction<String, String> stringSimilarity = (s1, s2) -> { int matches = 0; int length = Math.min(s1.length(), s2.length()); for (int i = 0; i < length; i++) { if (s1.charAt(i) == s2.charAt(i)) { matches++; } } return (double) matches / Math.max(s1.length(), s2.length()); }; // Format similarity score as percentage Function<Double, String> toPercent = score -> String.format("%.0f%%", score * 100); double similarity = stringSimilarity.applyAsDouble("hello", "hallo"); String percentage = toPercent.apply(similarity); System.out.println("String similarity: " + percentage); } }
此示例将 ToDoubleBiFunction 与 Function 结合使用。第一个计算字符串相似度(double),第二个将其格式化为百分比。这展示了函数式接口如何在处理管道中协同工作。
在流操作中使用
ToDoubleBiFunction 可以在流处理中使用。此示例计算产品对的平均单价。
package com.zetcode; import java.util.List; import java.util.function.ToDoubleBiFunction; public class Main { public static void main(String[] args) { // Calculate average price per unit for two products ToDoubleBiFunction<Product, Product> avgPricePerUnit = (p1, p2) -> (p1.price / p1.quantity + p2.price / p2.quantity) / 2; List<Product> products = List.of( new Product(5, 25.0), // 5 units for $25 new Product(3, 21.0), // 3 units for $21 new Product(10, 45.0) // 10 units for $45 ); // Compare each pair of products for (int i = 0; i < products.size(); i++) { for (int j = i + 1; j < products.size(); j++) { double avg = avgPricePerUnit.applyAsDouble( products.get(i), products.get(j)); System.out.printf("Avg price for pair %d-%d: $%.2f%n", i+1, j+1, avg); } } } } class Product { int quantity; double price; Product(int quantity, double price) { this.quantity = quantity; this.price = price; } }
此示例演示了 ToDoubleBiFunction 在嵌套循环中处理产品对。该函数使用原始 double 算术有效地计算平均单价。结果格式化以便显示。
专门的原始类型变体
Java 提供了 ToDoubleBiFunction 的专门版本,用于原始输入。这些避免了在使用原始数据类型时装箱开销。
package com.zetcode; import java.util.function.IntToDoubleFunction; import java.util.function.ToDoubleBiFunction; import java.util.function.ToIntBiFunction; public class Main { public static void main(String[] args) { // Standard ToDoubleBiFunction with Integer objects ToDoubleBiFunction<Integer, Integer> objCalc = (a, b) -> Math.sqrt(a * a + b * b); // Primitive specialized version (hypot is more accurate) ToDoubleBiFunction<Integer, Integer> primCalc = (a, b) -> Math.hypot(a, b); System.out.println("Object version result: " + objCalc.applyAsDouble(3, 4)); System.out.println("Primitive version result: " + primCalc.applyAsDouble(3, 4)); // Note: Java doesn't have IntIntToDoubleFunction, but hypot is optimized } }
此示例比较了标准方法和原始类型优化的方法。虽然 Java 没有 IntIntToDoubleFunction,但 Math.hypot 等方法已针对原始类型进行了优化。该示例展示了如何通过数值运算来最大化性能。
来源
在本文中,我们介绍了 Java ToDoubleBiFunction 接口的基本方法和功能。理解这些概念对于在现代 Java 应用程序中进行高效的数值处理至关重要。
作者
列出所有Java教程。