ZetCode

Java DoubleFunction 接口

最后修改时间:2025 年 4 月 16 日

java.util.function.DoubleFunction 接口表示一个接受 double 值参数并产生结果的函数。它是一个函数式接口,具有一个单一的抽象方法 apply。这种特殊化在处理基本类型 double 时避免了装箱开销。

DoubleFunction 是 Java 8 中添加的 Java 函数式编程实用程序的一部分。它在处理基本 double 值流时特别有用。该接口有助于编写更高效、更简洁的代码。

DoubleFunction 接口概述

DoubleFunction 接口包含一个抽象方法,该方法接受一个 double 并返回指定类型的结果。与常规 Function 不同,它使用基本类型 double 以获得更好的性能。

@FunctionalInterface
public interface DoubleFunction<R> {
    R apply(double value);
}

上面的代码展示了 DoubleFunction 的简单结构。它仅对返回类型 R 使用泛型。输入始终是基本类型 double。该接口使用 @FunctionalInterface 进行注解。

DoubleFunction 的基本用法

使用 DoubleFunction 的最简单方法是使用 lambda 表达式。我们定义如何将输入 double 转换为所需的输出类型。此示例将 double 转换为其字符串表示形式。

Main.java
package com.zetcode;

import java.util.function.DoubleFunction;

public class Main {

    public static void main(String[] args) {

        // Define a function that takes double and returns String
        DoubleFunction<String> doubleToString = d -> "Value: " + d;
        
        // Apply the function
        System.out.println(doubleToString.apply(3.1415));
        System.out.println(doubleToString.apply(2.71828));
        
        // Function with formatting
        DoubleFunction<String> formatted = d -> String.format("Formatted: %.2f", d);
        System.out.println(formatted.apply(1.23456789));
    }
}

此示例演示了使用 lambda 表达式的 DoubleFunction 基本用法。我们创建了两个函数,它们接受 double 并返回格式化的字符串。第二个函数直接在 lambda 中显示数字格式化。

带有方法引用的 DoubleFunction

方法引用为与 DoubleFunction 签名匹配的现有方法提供了简洁的语法。此示例使用 Double.toString 作为方法引用。

Main.java
package com.zetcode;

import java.util.function.DoubleFunction;

public class Main {

    public static void main(String[] args) {

        // Using method reference to Double.toString()
        DoubleFunction<String> toStringRef = Double::toString;
        
        System.out.println("String value: " + toStringRef.apply(123.456));
        
        // Using constructor reference
        DoubleFunction<Double> doubleConstructor = Double::new;
        Double d = doubleConstructor.apply(42.0);
        System.out.println("Created Double: " + d);
    }
}

此示例显示了带有方法和构造函数引用的 DoubleFunction。第一种情况使用 Double.toString() 方法。第二种情况演示了通过构造函数引用创建对象。

在流处理中使用 DoubleFunction

DoubleFunction 经常与 DoubleStream 一起使用,用于处理基本 double 值。与使用常规 Function 相比,这避免了装箱开销。

Main.java
package com.zetcode;

import java.util.stream.DoubleStream;

public class Main {

    public static void main(String[] args) {

        // Create DoubleStream of values
        DoubleStream stream = DoubleStream.of(1.1, 2.2, 3.3, 4.4, 5.5);
        
        // Process stream with DoubleFunction
        stream.mapToObj(d -> "Number: " + d * 2)
              .forEach(System.out::println);
              
        // Alternative with separate DoubleFunction
        DoubleFunction<String> formatter = d -> String.format("$%.2f", d);
        DoubleStream.of(9.99, 19.95, 29.50)
                   .mapToObj(formatter)
                   .forEach(System.out::println);
    }
}

此示例演示了在流处理中使用 DoubleFunction。我们同时使用内联 lambda 和单独的 DoubleFunction 来转换流元素。mapToObj 方法接受 DoubleFunction 以将 double 转换为对象。

用于数学运算的 DoubleFunction

DoubleFunction 非常适合接受 double 输入的数学运算。此示例显示了应用于输入值的各种数学转换。

Main.java
package com.zetcode;

import java.util.function.DoubleFunction;

public class Main {

    public static void main(String[] args) {

        // Square root function
        DoubleFunction<Double> sqrt = Math::sqrt;
        System.out.println("Square root of 16: " + sqrt.apply(16.0));
        
        // Trigonometric function
        DoubleFunction<Double> sinDegrees = d -> Math.sin(Math.toRadians(d));
        System.out.println("Sin of 30 degrees: " + sinDegrees.apply(30.0));
        
        // Custom mathematical operation
        DoubleFunction<String> quadratic = x -> {
            double result = 2*x*x + 3*x + 5;
            return "2x² + 3x + 5 for x=" + x + " is " + result;
        };
        System.out.println(quadratic.apply(2.0));
    }
}

此示例显示了用于数学运算的 DoubleFunction。我们使用现有 Math 方法的方法引用并定义自定义操作。该接口适用于简单和复杂的数学转换。

带有集合的 DoubleFunction

DoubleFunction 可用于处理包含 double 值的集合。此示例演示了将 double 数组转换为不同的表示形式。

Main.java
package com.zetcode;

import java.util.Arrays;
import java.util.List;
import java.util.function.DoubleFunction;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) {

        double[] values = {1.5, 2.5, 3.5, 4.5, 5.5};
        
        // Convert doubles to temperature strings
        DoubleFunction<String> toFahrenheit = c -> {
            double f = c * 9/5 + 32;
            return String.format("%.1f°C = %.1f°F", c, f);
        };
        
        List<String> temps = Arrays.stream(values)
                                 .mapToObj(toFahrenheit)
                                 .collect(Collectors.toList());
                                 
        temps.forEach(System.out::println);
        
        // Convert to measurement strings
        DoubleFunction<String> toInches = cm -> String.format("%.2f cm = %.2f in", cm, cm / 2.54);
        Arrays.stream(values).mapToObj(toInches).forEach(System.out::println);
    }
}

此示例显示了 DoubleFunction 处理基本 double 数组。我们将摄氏度转换为华氏度,将厘米转换为英寸。使用 mapToObj 的流处理是高效的,因为它避免了对单个元素进行装箱。

将 DoubleFunction 与其他函数式接口组合

DoubleFunction 可以与其他函数式接口组合以进行更复杂的操作。此示例显示了与 Predicate 和 Consumer 的组合。

Main.java
package com.zetcode;

import java.util.function.DoubleFunction;
import java.util.function.DoublePredicate;
import java.util.function.DoubleConsumer;

public class Main {

    public static void main(String[] args) {

        // Define predicate to check if value is positive
        DoublePredicate isPositive = d -> d > 0;
        
        // Define function to create description
        DoubleFunction<String> describer = d -> 
            isPositive.test(d) ? "Positive" : "Non-positive";
            
        // Define consumer to print results
        DoubleConsumer printer = d -> 
            System.out.println(d + " is " + describer.apply(d));
            
        // Test values
        printer.accept(3.14);
        printer.accept(-2.5);
        printer.accept(0.0);
        
        // Chain operations
        DoubleFunction<String> complexOp = d -> {
            double abs = Math.abs(d);
            double sqrt = Math.sqrt(abs);
            return String.format("|%.2f| = %.2f, √%.2f = %.2f", 
                                d, abs, abs, sqrt);
        };
        System.out.println(complexOp.apply(-16.0));
    }
}

此示例演示了将 DoubleFunction 与其他函数式接口组合。我们创建了一个流水线,用于检查值、描述它们并打印结果。复杂的操作展示了如何链接多个转换。

来源

Java DoubleFunction 接口文档

在本文中,我们介绍了 Java DoubleFunction 接口的基本方法和特性。理解这些概念有助于在现代 Java 应用程序中编写高效的数值处理代码。

作者

我的名字是 Jan Bodnar,我是一位敬业的程序员,在该领域拥有多年的经验。我从 2007 年开始撰写编程文章,此后撰写了 1,400 多篇文章和八本电子书。凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程