ZetCode

Java LongSupplier 接口

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

java.util.function.LongSupplier 接口表示提供 long 类型结果的供应者。它是一个函数式接口,只有一个抽象方法 getAsLong。LongSupplier 不接受任何参数,但会产生一个 long 值。

LongSupplier 是 Java 8 中添加的 Java 函数式编程实用程序的一部分。当您需要生成或提供 long 值而无需输入参数时,它很有用。此接口是 Supplier 针对 long 值的基本特化。

LongSupplier 接口概述

LongSupplier 接口包含一个必须实现的抽象方法。该接口使用 @FunctionalInterface 注解,以表明其单一抽象方法的特性。

@FunctionalInterface
public interface LongSupplier {
    long getAsLong();
}

上面的代码显示了 LongSupplier 的简单结构。它没有默认方法或静态方法,只有一个抽象方法 getAsLong,该方法返回一个原始 long 值。

LongSupplier 的基本用法

使用 LongSupplier 的最简单方法是使用 lambda 表达式。我们在 getAsLong 方法中定义如何生成 long 值。此示例显示了随机数生成。

Main.java
package com.zetcode;

import java.util.function.LongSupplier;

public class Main {

    public static void main(String[] args) {

        // Define a LongSupplier that returns random numbers
        LongSupplier randomSupplier = () -> (long) (Math.random() * 1000);
        
        // Get and print several random values
        System.out.println("Random 1: " + randomSupplier.getAsLong());
        System.out.println("Random 2: " + randomSupplier.getAsLong());
        System.out.println("Random 3: " + randomSupplier.getAsLong());
    }
}

此示例演示了使用 lambda 表达式的基本 LongSupplier 用法。randomSupplier 生成 0 到 1000 之间的随机数。每次调用 getAsLong 都会产生一个新的随机值。

带有方法引用的 LongSupplier

当现有方法与接口的签名匹配时,方法引用提供了一种简洁的方式来实现 LongSupplier。此示例使用 System.currentTimeMillis。

Main.java
package com.zetcode;

import java.util.function.LongSupplier;

public class Main {

    public static void main(String[] args) {

        // LongSupplier using method reference
        LongSupplier timeSupplier = System::currentTimeMillis;
        
        System.out.println("Current time: " + timeSupplier.getAsLong());
        
        // Wait a moment
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("Time after delay: " + timeSupplier.getAsLong());
    }
}

此示例显示了使用方法引用实现的 LongSupplier。timeSupplier 以毫秒为单位返回当前时间。方法引用通常比等效的 lambda 表达式更简洁。

有状态的 LongSupplier

LongSupplier 的实现可以在调用之间保持状态。此示例创建一个计数器,每次调用 getAsLong 都会递增。

Main.java
package com.zetcode;

import java.util.function.LongSupplier;

public class Main {

    public static void main(String[] args) {

        // Stateful LongSupplier
        LongSupplier counter = new LongSupplier() {
            private long count = 0;
            
            @Override
            public long getAsLong() {
                return ++count;
            }
        };
        
        System.out.println("Count 1: " + counter.getAsLong());
        System.out.println("Count 2: " + counter.getAsLong());
        System.out.println("Count 3: " + counter.getAsLong());
    }
}

此示例演示了一个有状态的 LongSupplier。计数器维护在调用之间保持的内部状态(计数)。每次 getAsLong 调用都会返回并递增计数器。这里使用了匿名类的语法。

在流生成中使用 LongSupplier

LongSupplier 与 Stream.generate 结合使用时,可用于创建无限的 long 值流。此示例生成一个斐波那契数列的流。

Main.java
package com.zetcode;

import java.util.function.LongSupplier;
import java.util.stream.LongStream;

public class Main {

    public static void main(String[] args) {

        // Fibonacci sequence generator
        LongSupplier fibSupplier = new LongSupplier() {
            private long previous = 0;
            private long current = 1;
            
            @Override
            public long getAsLong() {
                long next = previous + current;
                previous = current;
                current = next;
                return previous;
            }
        };
        
        // Generate first 10 Fibonacci numbers
        LongStream.generate(fibSupplier)
            .limit(10)
            .forEach(System.out::println);
    }
}

此示例显示了 LongSupplier 与 LongStream.generate 一起使用。fibSupplier 生成斐波那契数。该流限制为 10 个元素并打印。状态在流操作之间保持。

组合 LongSupplier

虽然 LongSupplier 没有组合方法,但我们可以手动组合它们来创建更复杂的供应者。此示例计算了两个其他供应者的平均值。

Main.java
package com.zetcode;

import java.util.function.LongSupplier;

public class Main {

    public static void main(String[] args) {

        // First supplier - system time modulo 1000
        LongSupplier timeSupplier = () -> System.currentTimeMillis() % 1000;
        
        // Second supplier - random numbers
        LongSupplier randomSupplier = () -> (long) (Math.random() * 1000);
        
        // Combined supplier - average of the two
        LongSupplier averageSupplier = () -> 
            (timeSupplier.getAsLong() + randomSupplier.getAsLong()) / 2;
        
        System.out.println("Average 1: " + averageSupplier.getAsLong());
        System.out.println("Average 2: " + averageSupplier.getAsLong());
    }
}

此示例演示了组合多个 LongSupplier。averageSupplier 返回来自 timeSupplier 和 randomSupplier 的值的平均值。这种模式允许从更简单的供应者构建复杂的供应者。

用于常量值的 LongSupplier

LongSupplier 可用于提供常量值,尽管这在 lambda 中比在方法引用中更惯用。这里我们提供一个常量。

Main.java
package com.zetcode;

import java.util.function.LongSupplier;

public class Main {

    public static void main(String[] args) {

        // Constant value supplier
        LongSupplier constantSupplier = () -> 42L;
        
        System.out.println("The answer: " + constantSupplier.getAsLong());
        
        // Another approach using lambda
        LongSupplier maxValueSupplier = () -> Long.MAX_VALUE;
        System.out.println("Max long: " + maxValueSupplier.getAsLong());
    }
}

此示例显示了返回常量值的 LongSupplier。虽然简单,但当 API 期望 LongSupplier 但您想提供固定值时,这很有用。L 后缀表示 Java 中的 long 字面量。

在 Optional 中使用 LongSupplier

LongSupplier 与 OptionalLong 的 orElseGet 方法一起使用,当 Optional 为空时,提供一个回退值。这显示了实际用法。

Main.java
package com.zetcode;

import java.util.OptionalLong;
import java.util.function.LongSupplier;

public class Main {

    public static void main(String[] args) {

        // Empty OptionalLong
        OptionalLong emptyOpt = OptionalLong.empty();
        
        // Supplier for default value
        LongSupplier defaultSupplier = () -> {
            System.out.println("Providing default value");
            return 100L;
        };
        
        // Get value or default from supplier
        long value1 = emptyOpt.orElseGet(defaultSupplier);
        System.out.println("Value 1: " + value1);
        
        // Non-empty Optional
        OptionalLong presentOpt = OptionalLong.of(200L);
        long value2 = presentOpt.orElseGet(defaultSupplier);
        System.out.println("Value 2: " + value2);
    }
}

此示例演示了与 OptionalLong 一起使用的 LongSupplier。当 Optional 为空时,defaultSupplier 提供一个回退值。仅在需要时才调用供应者,这使其对于昂贵的操作来说非常有效。

来源

Java LongSupplier 接口文档

在本文中,我们介绍了 Java LongSupplier 接口的基本特性和用法模式。理解这些概念有助于 Java 应用程序中的函数式编程和流处理。

作者

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

列出所有Java教程