ZetCode

Java LongConsumer 接口

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

java.util.function.LongConsumer 接口表示一个接受单个 long 类型参数且不返回任何结果的操作。它是一个函数式接口,只有一个抽象方法 accept。 LongConsumer 主要用于副作用,例如打印或修改状态。

LongConsumer 是 Java 8 中添加的 Java 函数式编程实用程序的一部分。 它专门用于原始 long 值,以避免装箱开销。 该接口通常与流和其他函数式结构一起使用。

LongConsumer 接口概述

LongConsumer 接口包含一个抽象方法和一个默认方法。 关键方法 accept 对输入执行操作。 andThen 方法支持消费者链。

@FunctionalInterface
public interface LongConsumer {
    void accept(long value);
    
    default LongConsumer andThen(LongConsumer after);
}

上面的代码显示了 LongConsumer 接口的结构。 它对原始 long 值进行操作。 该接口使用 @FunctionalInterface 注解,以表明其单个抽象方法的性质。

LongConsumer 的基本用法

使用 LongConsumer 的最简单方法是使用 lambda 表达式。 我们在 accept 方法中定义对 long 值要做什么。 示例打印 long 值。

Main.java
package com.zetcode;

import java.util.function.LongConsumer;

public class Main {

    public static void main(String[] args) {

        // Define a consumer that prints long values
        LongConsumer printConsumer = value -> System.out.println("Value: " + value);
        
        // Use the consumer
        printConsumer.accept(42L);
        printConsumer.accept(10000000000L);
        
        // Consumer with method reference
        LongConsumer sysOutConsumer = System.out::println;
        sysOutConsumer.accept(999L);
    }
}

此示例演示了使用 lambda 和方法引用的基本 LongConsumer 用法。 printConsumer 接受一个 long 值并打印它。 我们将其应用于不同的值。 方法引用为现有方法提供了简洁的语法。

带 andThen 的 LongConsumer

andThen 方法允许链接消费者,其中两个操作按顺序执行。 这使得能够从简单的消费者创建复杂的影响链。

Main.java
package com.zetcode;

import java.util.function.LongConsumer;

public class Main {

    public static void main(String[] args) {

        // First consumer prints the value
        LongConsumer printValue = value -> System.out.println("Original: " + value);
        
        // Second consumer prints the squared value
        LongConsumer printSquare = value -> 
            System.out.println("Squared: " + (value * value));
        
        // Chain the consumers
        LongConsumer combined = printValue.andThen(printSquare);
        
        combined.accept(5L);
        combined.accept(10L);
    }
}

此示例显示了使用 andThen 的消费者链。 输入值首先按原样打印,然后打印其平方。 两个消费者都接收相同的原始输入值。

带 Streams 的 LongConsumer

LongConsumer 通常与 LongStream 一起用于处理原始 long 值。 forEach 终端操作接受 LongConsumer 以执行副作用。

Main.java
package com.zetcode;

import java.util.stream.LongStream;

public class Main {

    public static void main(String[] args) {

        // Create a LongStream
        LongStream.rangeClosed(1L, 5L)
            // Filter even numbers
            .filter(n -> n % 2 == 0)
            // Use LongConsumer to print
            .forEach(value -> {
                System.out.println("Even value: " + value);
                System.out.println("Cube: " + (value * value * value));
            });
    }
}

此示例演示了 LongStream 中 LongConsumer 的用法。 我们过滤偶数,并使用 forEach 以及一个打印值及其立方的消费者。 Streams 提供了干净的数据处理管道。

有状态的 LongConsumer

当实现为一个类或使用外部变量时,LongConsumer 可以在每次调用之间维护状态。 这允许跨多个调用累积值。

Main.java
package com.zetcode;

import java.util.function.LongConsumer;

public class Main {

    public static void main(String[] args) {

        // Using an array to hold state (effectively final)
        long[] sum = {0L};
        
        // Consumer that accumulates values
        LongConsumer summingConsumer = value -> sum[0] += value;
        
        summingConsumer.accept(10L);
        summingConsumer.accept(20L);
        summingConsumer.accept(30L);
        
        System.out.println("Total sum: " + sum[0]);
        
        // Using a class implementation
        class AveragingConsumer implements LongConsumer {
            private long total = 0;
            private int count = 0;
            
            @Override
            public void accept(long value) {
                total += value;
                count++;
            }
            
            public double getAverage() {
                return count == 0 ? 0 : (double) total / count;
            }
        }
        
        AveragingConsumer avgConsumer = new AveragingConsumer();
        avgConsumer.accept(5L);
        avgConsumer.accept(15L);
        avgConsumer.accept(25L);
        
        System.out.println("Average: " + avgConsumer.getAverage());
    }
}

此示例显示了有状态的 LongConsumer 实现。 第一个使用一个数组在 lambda 中保存状态。 第二个使用一个类来跟踪总数和计数以计算平均值。 两者都在 accept 调用之间维护状态。

Collections 中的 LongConsumer

LongConsumer 可以与包含 long 值的集合一起使用。 我们可以通过将它们转换为流或直接迭代来处理集合。

Main.java
package com.zetcode;

import java.util.Arrays;
import java.util.List;
import java.util.function.LongConsumer;

public class Main {

    public static void main(String[] args) {

        List numbers = Arrays.asList(100L, 200L, 300L, 400L);
        
        // Consumer that formats and prints long values
        LongConsumer formatter = value -> 
            System.out.printf("Formatted: $%,d%n", value);
        
        // Process list with stream
        numbers.stream()
            .mapToLong(Long::longValue)
            .forEach(formatter);
            
        // Process array directly
        long[] primitives = {1000L, 2000L, 3000L};
        Arrays.stream(primitives)
            .forEach(formatter.andThen(
                v -> System.out.println("---")));
    }
}

此示例显示了 LongConsumer 与集合的用法。 我们处理一个 List通过转换为 LongStream。 我们也直接处理一个原始 long 数组。 消费者将值格式化为货币并打印它们。

将 LongConsumer 与其他函数式接口结合使用

LongConsumer 可以与其他函数式接口结合使用以创建更复杂的操作。 这演示了函数式类型之间的互操作性。

Main.java
package com.zetcode;

import java.util.function.LongConsumer;
import java.util.function.LongFunction;
import java.util.function.LongPredicate;

public class Main {

    public static void main(String[] args) {

        // Predicate to filter negative numbers
        LongPredicate isPositive = n -> n > 0;
        
        // Function to convert long to String
        LongFunction toStringWithUnit = n -> n + " meters";
        
        // Consumer to print processed values
        LongConsumer printer = n -> 
            System.out.println("Processed: " + toStringWithUnit.apply(n));
        
        // Process values
        long[] values = {10, -5, 20, -3, 30};
        
        for (long n : values) {
            if (isPositive.test(n)) {
                printer.accept(n);
            }
        }
        
        // Using method that accepts LongConsumer
        processValues(15L, 25L, printer.andThen(
            n -> System.out.println("--- End of record ---")));
    }
    
    private static void processValues(long... values, LongConsumer consumer) {
        for (long n : values) {
            consumer.accept(n);
        }
    }
}

此示例将 LongConsumer 与 LongPredicate 和 LongFunction 结合使用。 我们过滤正数,将它们转换为带单位的字符串,然后打印它们。 该示例还显示了将 LongConsumer 传递给方法。

来源

Java LongConsumer 接口文档

在本文中,我们介绍了 Java LongConsumer 接口的基本方法和特性。 了解这些概念对于在现代 Java 应用程序中使用原始 long 值进行函数式编程至关重要。

作者

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

列出所有Java教程