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教程。