Java ObjLongConsumer 接口
最后修改时间:2025 年 4 月 16 日
java.util.function.ObjLongConsumer
接口代表一个接受对象和 long 类型参数的操作。它是一个函数式接口,只有一个抽象方法 accept
。该接口专门用于 long 原始类型,以避免装箱开销。
ObjLongConsumer
是 Java 8 中添加的 Java 函数式编程实用程序的一部分。它允许行为参数化,用于需要对象和 long 参数的操作。该接口常用于流处理和集合操作。
ObjLongConsumer 接口概述
ObjLongConsumer
接口包含一个抽象方法,该方法对给定的参数执行操作。与常规的消费者不同,它接受两个参数 - 一个对象和一个 long 原始类型。
@FunctionalInterface public interface ObjLongConsumer<T> { void accept(T t, long value); }
上面的代码显示了 ObjLongConsumer
接口的结构。它对对象参数使用泛型,而第二个参数始终是 long 类型。该接口用 @FunctionalInterface 标注。
ObjLongConsumer 的基本用法
使用 ObjLongConsumer 的最简单方法是使用 lambda 表达式。我们在 accept 方法中定义如何处理对象和 long 参数。此示例展示了一个记录产品更新的消费者。
package com.zetcode; import java.util.function.ObjLongConsumer; public class Main { public static void main(String[] args) { // Define a consumer for product updates ObjLongConsumer<String> productUpdater = (name, newStock) -> { System.out.printf("Updating product '%s' with new stock: %d%n", name, newStock); }; // Use the consumer productUpdater.accept("Laptop", 150L); productUpdater.accept("Smartphone", 300L); } }
此示例演示了 ObjLongConsumer
的基本用法。productUpdater 接受产品名称(String)和新的库存值(long)。它打印每件产品的更新消息。消费者执行一个动作,不返回任何结果。
ObjLongConsumer 与集合
ObjLongConsumer
可用于处理集合中的元素。此示例演示了如何更新地图中产品的库存数量。
package com.zetcode; import java.util.HashMap; import java.util.Map; import java.util.function.ObjLongConsumer; public class Main { public static void main(String[] args) { Map<String, Long> inventory = new HashMap<>(); inventory.put("Keyboard", 50L); inventory.put("Mouse", 75L); inventory.put("Monitor", 30L); // Consumer to update inventory ObjLongConsumer<String> inventoryUpdater = (product, quantity) -> { inventory.merge(product, quantity, Long::sum); }; // Apply updates inventoryUpdater.accept("Keyboard", 20L); inventoryUpdater.accept("Monitor", 15L); inventoryUpdater.accept("Headphones", 40L); // New product System.out.println("Updated inventory: " + inventory); } }
此示例展示了 ObjLongConsumer 与集合。inventoryUpdater 将数量添加到现有产品或创建新条目。Map.merge 方法处理这两种情况。这种模式对于批量更新很有用。
ObjLongConsumer 在流处理中
ObjLongConsumer
可用于需要同时处理对象和 long 值的流操作。此示例计算订单项目的总价格。
package com.zetcode; import java.util.List; import java.util.function.ObjLongConsumer; public class Main { public static void main(String[] args) { record OrderItem(String name, double price, int quantity) {} List<OrderItem> orderItems = List.of( new OrderItem("Shirt", 29.99, 2), new OrderItem("Pants", 49.99, 1), new OrderItem("Shoes", 89.99, 1) ); // Consumer to calculate total price ObjLongConsumer<OrderItem> priceCalculator = (item, total) -> { double itemTotal = item.price() * item.quantity(); System.out.printf("%s: %.2f x %d = %.2f (Running total: %d)%n", item.name(), item.price(), item.quantity(), itemTotal, total + (long) itemTotal); }; // Process with running total long runningTotal = 0; for (OrderItem item : orderItems) { priceCalculator.accept(item, runningTotal); runningTotal += (long) (item.price() * item.quantity()); } } }
此示例演示了 ObjLongConsumer 在类似流的处理中。priceCalculator 显示每个项目的总额和运行总和。虽然没有直接使用 Stream API,但它展示了用于顺序处理的消费者模式。
ObjLongConsumer 与原始数组
ObjLongConsumer
适用于原始数组,我们需要使用附加上下文处理元素。此示例使用位置信息处理温度读数。
package com.zetcode; import java.util.function.ObjLongConsumer; public class Main { public static void main(String[] args) { long[] temperatures = {22L, 24L, 19L, 21L, 25L}; String location = "New York"; // Consumer to process temperature readings ObjLongConsumer<String> tempProcessor = (loc, temp) -> { String condition = temp > 23 ? "Warm" : temp < 20 ? "Cool" : "Mild"; System.out.printf("%s: %d°C (%s)%n", loc, temp, condition); }; // Process all temperatures for (long temp : temperatures) { tempProcessor.accept(location, temp); } } }
此示例展示了 ObjLongConsumer 与原始数组。tempProcessor 接受位置上下文和温度值。它对每个读数进行分类并打印格式化的消息。消费者处理对象和原始类型。
ObjLongConsumer 用于对象状态修改
ObjLongConsumer
可以根据 long 参数修改对象状态。此示例使用交易金额更新银行帐户余额。
package com.zetcode; import java.util.function.ObjLongConsumer; public class Main { static class BankAccount { private String owner; private long balance; public BankAccount(String owner, long balance) { this.owner = owner; this.balance = balance; } public void processTransaction(ObjLongConsumer<BankAccount> operation, long amount) { operation.accept(this, amount); } @Override public String toString() { return owner + "'s account: $" + balance; } } public static void main(String[] args) { BankAccount account = new BankAccount("John", 1000L); // Define deposit operation ObjLongConsumer<BankAccount> deposit = (acc, amount) -> { acc.balance += amount; System.out.println("Deposited: $" + amount); }; // Define withdrawal operation ObjLongConsumer<BankAccount> withdraw = (acc, amount) -> { if (acc.balance >= amount) { acc.balance -= amount; System.out.println("Withdrawn: $" + amount); } else { System.out.println("Insufficient funds for withdrawal: $" + amount); } }; // Process transactions account.processTransaction(deposit, 500L); System.out.println(account); account.processTransaction(withdraw, 200L); System.out.println(account); account.processTransaction(withdraw, 2000L); System.out.println(account); } }
此示例演示了使用 ObjLongConsumer
的状态修改。BankAccount 类使用消费者进行存款和取款。每个操作都接收帐户对象和交易金额。这封装了行为。
ObjLongConsumer 在方法参数中
ObjLongConsumer
可以作为方法参数传递,以实现灵活的行为。此示例显示了一个接受消费者的通用数据处理器。
package com.zetcode; import java.util.function.ObjLongConsumer; public class Main { static void processData(String[] items, long[] values, ObjLongConsumer<String> processor) { if (items.length != values.length) { throw new IllegalArgumentException("Arrays must have equal length"); } for (int i = 0; i < items.length; i++) { processor.accept(items[i], values[i]); } } public static void main(String[] args) { String[] products = {"Tablet", "Laptop", "Phone"}; long[] sales = {1500L, 2300L, 3100L}; // Consumer to print product sales ObjLongConsumer<String> salesReporter = (product, count) -> { System.out.printf("%-10s: %5d units%n", product, count); }; // Consumer to calculate revenue (assuming $500 per unit) ObjLongConsumer<String> revenueCalculator = (product, count) -> { long revenue = count * 500; System.out.printf("%-10s: $%,d%n", product, revenue); }; System.out.println("Sales Report:"); processData(products, sales, salesReporter); System.out.println("\nRevenue Estimate:"); processData(products, sales, revenueCalculator); } }
此示例展示了 ObjLongConsumer 作为方法参数。processData 方法接受任何消费者来处理成对的 String 和 long 值。不同的消费者提供了不同的处理方式,而无需修改核心方法。
将 ObjLongConsumer 与其他函数式接口结合使用
ObjLongConsumer
可以与其他函数式接口结合使用,以进行更复杂的操作。此示例展示了在消费之前进行过滤。
package com.zetcode; import java.util.function.ObjLongConsumer; import java.util.function.LongPredicate; public class Main { public static void main(String[] args) { record SensorReading(String sensorId, long value) {} SensorReading[] readings = { new SensorReading("TEMP-1", 22L), new SensorReading("TEMP-2", 45L), // Invalid new SensorReading("TEMP-3", 18L), new SensorReading("TEMP-4", 50L) // Invalid }; // Predicate to validate readings LongPredicate isValid = value -> value >= 20L && value <= 30L; // Consumer to process valid readings ObjLongConsumer<String> readingProcessor = (id, value) -> { System.out.printf("Processing valid reading - %s: %d%n", id, value); // Additional processing logic here }; // Process readings with filter for (SensorReading reading : readings) { if (isValid.test(reading.value())) { readingProcessor.accept(reading.sensorId(), reading.value()); } else { System.out.printf("Skipping invalid reading - %s: %d%n", reading.sensorId(), reading.value()); } } } }
此示例将 ObjLongConsumer 与 LongPredicate 结合使用。isValid 谓词在处理之前过滤读数。readingProcessor 仅接收有效值。这种模式实现了关注点的清晰分离。
来源
在本文中,我们介绍了 Java ObjLongConsumer 接口的基本方法和特性。了解这些概念对于有效处理需要对象和 long 原始类型参数的操作至关重要。
作者
列出所有Java教程。