ZetCode

Java ObjDoubleConsumer 接口

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

java.util.function.ObjDoubleConsumer 接口表示一个接受对象值和双精度浮点值作为参数的操作。它是一个函数式接口,具有单个抽象方法 accept。该接口对于需要使用两种不同类型的操作非常有用。

ObjDoubleConsumer 是 Java 8 中添加的 Java 函数式编程实用程序的一部分。它允许对使用对象和双精度值的操作进行行为参数化。该接口不返回任何结果。

ObjDoubleConsumer 接口概述

ObjDoubleConsumer 接口包含一个抽象方法,该方法对给定的参数执行操作。与某些其他函数式接口不同,它没有提供用于组合的默认方法。

@FunctionalInterface
public interface ObjDoubleConsumer<T> {
    void accept(T t, double value);
}

上面的代码显示了 ObjDoubleConsumer 接口的结构。它使用泛型,其中 T 是对象类型参数。该接口使用 @FunctionalInterface 注释来指示其单个抽象方法。

ObjDoubleConsumer 的基本用法

使用 ObjDoubleConsumer 的最简单方法是使用 lambda 表达式。我们在 accept 方法中定义如何使用对象和双精度值。该示例显示了一个打印两个值的消费者。

Main.java
package com.zetcode;

import java.util.function.ObjDoubleConsumer;

public class Main {

    public static void main(String[] args) {

        // Define a consumer that prints object and double
        ObjDoubleConsumer<String> printer = (s, d) ->
            System.out.println("String: " + s + ", Double: " + d);
        
        // Use the consumer
        printer.accept("Price", 19.99);
        printer.accept("Weight", 2.5);
        
        // Consumer with more complex logic
        ObjDoubleConsumer<String> formatter = (label, value) ->
            System.out.printf("%s: %.2f%n", label, value);
        formatter.accept("Temperature", 23.4567);
    }
}

此示例演示了使用 lambda 表达式的基本 ObjDoubleConsumer 用法。打印机消费者接受一个字符串和一个双精度值,并打印这两个值。格式化程序显示了双精度值的更复杂的格式化。消费者不返回值。

将 ObjDoubleConsumer 与集合一起使用

在处理需要将对象与双精度值关联的集合时,ObjDoubleConsumer 可能会很有用。此示例显示了处理产品价格映射。

Main.java
package com.zetcode;

import java.util.HashMap;
import java.util.Map;
import java.util.function.ObjDoubleConsumer;

public class Main {

    public static void main(String[] args) {

        Map<String, Double> products = new HashMap<>();
        products.put("Laptop", 999.99);
        products.put("Mouse", 25.50);
        products.put("Keyboard", 49.99);
        
        // Consumer to apply discount
        ObjDoubleConsumer<String> discountApplier = (name, price) -> {
            double discounted = price * 0.9; // 10% discount
            System.out.printf("%s: $%.2f -> $%.2f%n", name, price, discounted);
        };
        
        // Apply to all products
        products.forEach(discountApplier::accept);
    }
}

此示例显示了与 Map 一起使用的 ObjDoubleConsumer。折扣应用者消费者计算并打印折扣价格。我们使用 forEach 与方法引用语法,将消费者应用于所有映射条目。

ObjDoubleConsumer 在对象处理中

我们可以使用 ObjDoubleConsumer 根据双精度值修改对象属性。此示例演示了更新产品库存数量。

Main.java
package com.zetcode;

import java.util.function.ObjDoubleConsumer;

class Product {
    String name;
    double quantity;
    
    Product(String name, double quantity) {
        this.name = name;
        this.quantity = quantity;
    }
    
    void display() {
        System.out.printf("%s: %.1f kg%n", name, quantity);
    }
}

public class Main {

    public static void main(String[] args) {

        Product apple = new Product("Apple", 10.5);
        Product banana = new Product("Banana", 7.2);
        
        // Consumer to add to inventory
        ObjDoubleConsumer<Product> addToStock = (p, q) -> p.quantity += q;
        
        // Apply consumer
        addToStock.accept(apple, 2.3);
        addToStock.accept(banana, 1.8);
        
        apple.display();
        banana.display();
    }
}

此示例显示了修改对象状态的 ObjDoubleConsumer。addToStock 消费者增加了产品数量。消费者直接根据提供的双精度值修改 Product 对象的 quantity 字段。

ObjDoubleConsumer 与基本类型数组

ObjDoubleConsumer 可以处理数组,我们需要将对象与双精度值关联。此示例计算加权分数。

Main.java
package com.zetcode;

import java.util.function.ObjDoubleConsumer;

public class Main {

    public static void main(String[] args) {

        String[] students = {"Alice", "Bob", "Charlie"};
        double[] weights = {0.3, 0.4, 0.3};
        double[] scores = {85.0, 92.0, 78.0};
        
        // Consumer to calculate weighted score
        ObjDoubleConsumer<String> scoreCalculator = (name, weight) -> {
            int index = java.util.Arrays.asList(students).indexOf(name);
            double weighted = scores[index] * weight;
            System.out.printf("%s: %.1f * %.1f = %.1f%n", 
                name, scores[index], weight, weighted);
        };
        
        // Process each student
        for (int i = 0; i < students.length; i++) {
            scoreCalculator.accept(students[i], weights[i]);
        }
    }
}

此示例演示了 ObjDoubleConsumer 处理并行数组。scoreCalculator 消费者将每个学生与其权重和分数匹配。它计算并打印每个学生的加权分数。

将 ObjDoubleConsumer 与其他接口结合使用

ObjDoubleConsumer 可以与其他函数式接口结合使用,以进行更复杂的操作。此示例显示了在消费之前进行过滤。

Main.java
package com.zetcode;

import java.util.function.ObjDoubleConsumer;
import java.util.function.DoublePredicate;

public class Main {

    public static void main(String[] args) {

        // Consumer for high-value transactions
        ObjDoubleConsumer<String> transactionLogger = (account, amount) ->
            System.out.printf("Large transaction: %s - $%.2f%n", account, amount);
        
        // Predicate to filter high amounts
        DoublePredicate isLarge = amount -> amount >= 1000.0;
        
        // Process transactions
        processTransaction("ACCT-123", 1500.0, isLarge, transactionLogger);
        processTransaction("ACCT-456", 500.0, isLarge, transactionLogger);
    }
    
    static void processTransaction(String account, double amount,
            DoublePredicate filter, ObjDoubleConsumer<String> consumer) {
        if (filter.test(amount)) {
            consumer.accept(account, amount);
        }
    }
}

此示例将 ObjDoubleConsumer 与 DoublePredicate 结合使用。processTransaction 方法仅在金额通过过滤器时调用消费者。这种模式使操作能够灵活组合。

ObjDoubleConsumer 在流处理中

虽然不像某些其他函数式接口那样直接用于流,但 ObjDoubleConsumer 仍然可以在流管道中发挥作用。此示例显示了处理流结果。

Main.java
package com.zetcode;

import java.util.function.ObjDoubleConsumer;
import java.util.stream.DoubleStream;

public class Main {

    public static void main(String[] args) {

        // Consumer to accumulate statistics
        class Stats {
            double sum = 0;
            int count = 0;
        }
        Stats stats = new Stats();
        
        ObjDoubleConsumer<Stats> statsUpdater = (s, value) -> {
            s.sum += value;
            s.count++;
        };
        
        // Process stream of doubles
        DoubleStream.of(12.5, 8.3, 15.7, 20.1, 5.4)
            .forEach(d -> statsUpdater.accept(stats, d));
        
        System.out.printf("Count: %d, Sum: %.1f, Avg: %.2f%n",
            stats.count, stats.sum, stats.sum / stats.count);
    }
}

此示例使用 ObjDoubleConsumer 从 DoubleStream 累积统计信息。statsUpdater 消费者在 Stats 对象中维护运行总数。这显示了消费者如何在流处理期间维护状态。

消费者的专业化变体

Java 提供了几个针对不同输入类型组合的专业化消费者接口。这些包括 BiConsumerDoubleConsumer 和其他用于各种基本类型。

Main.java
package com.zetcode;

import java.util.function.BiConsumer;
import java.util.function.DoubleConsumer;
import java.util.function.ObjDoubleConsumer;

public class Main {

    public static void main(String[] args) {

        // ObjDoubleConsumer example
        ObjDoubleConsumer<String> objDoublePrinter = (s, d) ->
            System.out.println(s + ": " + d);
        objDoublePrinter.accept("Value", 3.14);
        
        // BiConsumer example (two generic types)
        BiConsumer<String, Double> biPrinter = (s, d) ->
            System.out.println(s + ": " + d);
        biPrinter.accept("BiValue", 2.71);
        
        // DoubleConsumer example (primitive specialization)
        DoubleConsumer doublePrinter = d ->
            System.out.println("Double: " + d);
        doublePrinter.accept(1.618);
    }
}

此示例将 ObjDoubleConsumer 与相关接口进行比较。BiConsumer 更通用,但需要装箱,而 DoubleConsumer 仅处理基本类型双精度。根据特定需求进行选择。

来源

Java ObjDoubleConsumer 接口文档

在本文中,我们涵盖了 Java ObjDoubleConsumer 接口的基本方法和特性。理解这些概念有助于编写用于使用对象和双精度值的操作的表达性代码。

作者

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

列出所有Java教程