Java ToDoubleFunction 接口
最后修改时间:2025 年 4 月 16 日
java.util.function.ToDoubleFunction 接口表示一个接受一个参数并产生 double 类型结果的函数。它是一个函数式接口,具有单个抽象方法 applyAsDouble。
ToDoubleFunction 是 Java 8 中添加的 Java 函数式编程实用程序的一部分。它经过专门设计,在处理基本 double 值时避免装箱。这提高了数值运算的性能。
ToDoubleFunction 接口概述
ToDoubleFunction 接口包含一个必须实现的抽象方法。该方法接受一个 T 类型的对象并返回一个基本 double 值。此接口中没有默认方法。
@FunctionalInterface
public interface ToDoubleFunction<T> {
double applyAsDouble(T value);
}
上面的代码显示了 ToDoubleFunction 的简单结构。它使用泛型,其中 T 是输入类型。该接口使用 @FunctionalInterface 进行注解,以表明其单个抽象方法的性质。
ToDoubleFunction 的基本用法
使用 ToDoubleFunction 的最简单方法是使用 lambda 表达式。我们定义了如何将输入转换为 double 值。此示例计算字符串长度。
package com.zetcode;
import java.util.function.ToDoubleFunction;
public class Main {
public static void main(String[] args) {
// Define function that returns string length as double
ToDoubleFunction<String> lengthFunction = s -> (double) s.length();
// Apply the function
System.out.println("Length of 'hello': " + lengthFunction.applyAsDouble("hello"));
System.out.println("Length of 'functional': " + lengthFunction.applyAsDouble("functional"));
// Using method reference
ToDoubleFunction<String> lengthMethodRef = String::length;
System.out.println("Length via method ref: " + lengthMethodRef.applyAsDouble("method"));
}
}
此示例演示了使用 lambda 和方法引用的基本 ToDoubleFunction 用法。该函数接受 String 并返回其长度作为 double。我们将其应用于不同的字符串。方法引用提供了简洁的语法。
带有自定义对象的 ToDoubleFunction
ToDoubleFunction 适用于自定义对象。我们可以从对象中提取数值属性。此示例计算产品税后价格。
package com.zetcode;
import java.util.function.ToDoubleFunction;
class Product {
String name;
double price;
Product(String name, double price) {
this.name = name;
this.price = price;
}
}
public class Main {
public static void main(String[] args) {
// Function to calculate price with 20% tax
ToDoubleFunction<Product> priceWithTax = p -> p.price * 1.20;
Product laptop = new Product("Laptop", 999.99);
Product phone = new Product("Phone", 599.99);
System.out.println("Laptop with tax: " + priceWithTax.applyAsDouble(laptop));
System.out.println("Phone with tax: " + priceWithTax.applyAsDouble(phone));
}
}
此示例显示了带有自定义 Product 对象的 ToDoubleFunction。该函数计算包含税费的最终价格。我们将其应用于不同的产品实例。结果始终是基本 double 类型。
在 Stream 操作中使用 ToDoubleFunction
ToDoubleFunction 经常与 Java Stream 一起使用,用于数值转换。mapToDouble 操作接受一个 ToDoubleFunction。这使得能够进行有效的数值处理。
package com.zetcode;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
// Calculate average word length
double avgLength = words.stream()
.mapToDouble(String::length) // ToDoubleFunction as method reference
.average()
.orElse(0);
System.out.println("Average word length: " + avgLength);
// Sum of squares of lengths
double sumSquares = words.stream()
.mapToDouble(s -> Math.pow(s.length(), 2)) // Lambda as ToDoubleFunction
.sum();
System.out.println("Sum of squares: " + sumSquares);
}
}
此示例演示了在 Streams 中使用 ToDoubleFunction。我们使用方法引用和 lambda 将字符串转换为数值。流操作使用基本 double 类型以获得更好的性能。
带有集合的 ToDoubleFunction
ToDoubleFunction 可用于需要数值转换的集合操作。此示例显示了对集合的统计计算。
package com.zetcode;
import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.function.ToDoubleFunction;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50);
// Convert integers to their square roots
ToDoubleFunction<Integer> sqrtFunction = n -> Math.sqrt(n);
DoubleSummaryStatistics stats = numbers.stream()
.mapToDouble(sqrtFunction)
.summaryStatistics();
System.out.println("Count: " + stats.getCount());
System.out.println("Average: " + stats.getAverage());
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());
System.out.println("Sum: " + stats.getSum());
}
}
此示例使用 ToDoubleFunction 计算整数的平方根。然后,我们从结果中生成统计数据。该函数能够在统计操作之前进行干净的数值转换。
带有数组的 ToDoubleFunction
使用 ToDoubleFunction 可以有效地处理数组。此示例显示了数组转换和归约操作。
package com.zetcode;
import java.util.Arrays;
import java.util.function.ToDoubleFunction;
public class Main {
public static void main(String[] args) {
String[] temperatures = {"23.5", "18.2", "31.7", "25.0", "19.8"};
// Parse strings to doubles
ToDoubleFunction<String> parseDouble = s -> Double.parseDouble(s);
double[] values = Arrays.stream(temperatures)
.mapToDouble(parseDouble)
.toArray();
System.out.println("Parsed values: " + Arrays.toString(values));
// Find maximum temperature
double max = Arrays.stream(temperatures)
.mapToDouble(Double::parseDouble) // Method reference alternative
.max()
.orElse(Double.NaN);
System.out.println("Maximum temperature: " + max);
}
}
此示例处理一个温度字符串数组。我们使用 ToDoubleFunction 将字符串解析为 double 类型。结果收集在一个数组中,用于查找最大值。同时显示了 lambda 和方法引用的形式。
将 ToDoubleFunction 与其他函数式接口结合使用
ToDoubleFunction 可以与其他函数式接口结合使用,以进行更复杂的操作。此示例显示了在转换之前的过滤。
package com.zetcode;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.function.ToDoubleFunction;
public class Main {
public static void main(String[] args) {
List<String> mixedValues = Arrays.asList("12.5", "invalid", "45.2", "0", "3.14");
Predicate<String> isNumeric = s -> {
try {
Double.parseDouble(s);
return true;
} catch (NumberFormatException e) {
return false;
}
};
ToDoubleFunction<String> parseSafe = s -> {
try {
return Double.parseDouble(s);
} catch (NumberFormatException e) {
return 0.0;
}
};
// Filter valid numbers and parse them
double sum = mixedValues.stream()
.filter(isNumeric)
.mapToDouble(parseSafe)
.sum();
System.out.println("Sum of valid numbers: " + sum);
// Alternative with handling in ToDoubleFunction
double sumAlt = mixedValues.stream()
.mapToDouble(parseSafe)
.sum();
System.out.println("Sum with default handling: " + sumAlt);
}
}
此示例结合了 Predicate 和 ToDoubleFunction,以安全地处理混合输入。我们首先过滤有效数字,然后解析它们。另一种方法是在 ToDoubleFunction 本身中处理无效值。
基本类型特化比较
Java 提供了几个针对基本类型的函数式接口。此示例将 ToDoubleFunction 与针对不同基本类型的类似接口进行比较。
package com.zetcode;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
public class Main {
public static void main(String[] args) {
// Different primitive specialized functions
ToIntFunction<String> toLengthInt = String::length;
ToLongFunction<String> toLengthLong = s -> (long) s.length();
ToDoubleFunction<String> toLengthDouble = s -> (double) s.length();
System.out.println("As int: " + toLengthInt.applyAsInt("hello"));
System.out.println("As long: " + toLengthLong.applyAsLong("world"));
System.out.println("As double: " + toLengthDouble.applyAsDouble("java"));
// When precision matters
ToDoubleFunction<Double> circleArea = r -> Math.PI * r * r;
System.out.println("Area of circle with r=2.5: " + circleArea.applyAsDouble(2.5));
}
}
此示例将 ToDoubleFunction 与 ToIntFunction 和 ToLongFunction 进行比较。每个接口都专门用于不同的基本返回类型。当需要小数精度时,ToDoubleFunction 是理想的选择,例如在几何计算中。
来源
在本文中,我们介绍了 Java ToDoubleFunction 接口的基本使用模式。这个专门的函数式接口对于在 Java 应用程序中进行有效的数值处理非常有用。
作者
列出所有Java教程。