ZetCode

Java LongPredicate 接口

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

java.util.function.LongPredicate 接口表示一个对一个 long 类型参数的谓词(布尔值函数)。它是一个函数式接口,具有单个抽象方法 test

LongPredicate 是 Java 8 中添加的函数式编程实用程序的一部分。它专门用于 long 原语,以避免装箱开销。该接口提供了用于谓词组合的默认方法。

LongPredicate 接口概述

LongPredicate 包含一个抽象方法和几个默认方法。关键方法 test 在给定的 long 值上评估谓词。其他方法支持谓词之间的逻辑运算。

@FunctionalInterface
public interface LongPredicate {
    boolean test(long value);
    
    default LongPredicate and(LongPredicate other);
    default LongPredicate or(LongPredicate other);
    default LongPredicate negate();
}

以上代码显示了 LongPredicate 接口的结构。它使用 @FunctionalInterface 注解来表明其单个抽象方法的性质。默认方法支持谓词之间的逻辑运算。

LongPredicate 的基本用法

使用 LongPredicate 的最简单方法是使用 lambda 表达式。我们定义了用于测试 long 值的条件。示例检查数字是否为偶数。

Main.java
package com.zetcode;

import java.util.function.LongPredicate;

public class Main {

    public static void main(String[] args) {

        // Check if number is even
        LongPredicate isEven = n -> n % 2 == 0;
        
        System.out.println("Is 10 even? " + isEven.test(10));
        System.out.println("Is 15 even? " + isEven.test(15));
        
        // Check if number is positive
        LongPredicate isPositive = n -> n > 0;
        System.out.println("Is -5 positive? " + isPositive.test(-5));
    }
}

此示例演示了 LongPredicate 与 lambda 表达式的基本用法。我们创建了两个谓词:一个检查偶数,另一个检查正数。test 方法使用不同的值评估每个谓词。

使用 AND 组合谓词

and 方法允许使用逻辑 AND 组合两个谓词。两个谓词都必须返回 true,组合后的谓词才能返回 true。这使得可以从简单的条件创建复杂的条件。

Main.java
package com.zetcode;

import java.util.function.LongPredicate;

public class Main {

    public static void main(String[] args) {

        LongPredicate isEven = n -> n % 2 == 0;
        LongPredicate isGreaterThanTen = n -> n > 10;
        
        // Combine predicates with AND
        LongPredicate isEvenAndGreaterThanTen = isEven.and(isGreaterThanTen);
        
        System.out.println("12: " + isEvenAndGreaterThanTen.test(12));
        System.out.println("8: " + isEvenAndGreaterThanTen.test(8));
        System.out.println("15: " + isEvenAndGreaterThanTen.test(15));
    }
}

此示例显示了使用 and 组合谓词。我们检查数字是否既是偶数又大于 10。组合后的谓词仅在满足这两个条件时才返回 true。

使用 OR 组合谓词

or 方法使用逻辑 OR 组合两个谓词。任何一个谓词都可以返回 true,组合后的谓词就可以返回 true。这对于检查多个可能的条件很有用。

Main.java
package com.zetcode;

import java.util.function.LongPredicate;

public class Main {

    public static void main(String[] args) {

        LongPredicate isNegative = n -> n < 0;
        LongPredicate isGreaterThanHundred = n -> n > 100;
        
        // Combine predicates with OR
        LongPredicate isOutOfRange = isNegative.or(isGreaterThanHundred);
        
        System.out.println("-5: " + isOutOfRange.test(-5));
        System.out.println("50: " + isOutOfRange.test(50));
        System.out.println("150: " + isOutOfRange.test(150));
    }
}

此示例演示了使用 or 组合谓词。我们检查数字是负数还是大于 100。组合后的谓词在满足任何一个条件时返回 true。

否定谓词

negate 方法返回一个表示原始谓词逻辑否定的谓词。这等效于将逻辑 NOT 运算符应用于谓词的结果。

Main.java
package com.zetcode;

import java.util.function.LongPredicate;

public class Main {

    public static void main(String[] args) {

        LongPredicate isPrime = n -> {
            if (n < 2) return false;
            for (long i = 2; i <= Math.sqrt(n); i++) {
                if (n % i == 0) return false;
            }
            return true;
        };
        
        // Create negation of isPrime
        LongPredicate isNotPrime = isPrime.negate();
        
        System.out.println("7 is prime? " + isPrime.test(7));
        System.out.println("8 is not prime? " + isNotPrime.test(8));
    }
}

此示例显示了使用 negate 否定谓词。我们创建了一个素数检查器,然后对其取反以检查非素数。取反的谓词返回原始谓词的相反值。

将 LongPredicate 与 Streams 一起使用

LongPredicate 通常与 LongStream 一起用于过滤操作。filter 方法接受一个 LongPredicate,以包括与条件匹配的元素。这使得可以有效地处理 long 值。

Main.java
package com.zetcode;

import java.util.stream.LongStream;

public class Main {

    public static void main(String[] args) {

        // Define a range of numbers
        LongStream numbers = LongStream.rangeClosed(1, 20);
        
        // Filter for numbers divisible by 3 or 5
        LongPredicate divisibleBy3or5 = n -> n % 3 == 0 || n % 5 == 0;
        
        System.out.println("Numbers divisible by 3 or 5:");
        numbers.filter(divisibleBy3or5)
               .forEach(System.out::println);
    }
}

此示例演示了 LongPredicate 与 LongStream 的用法。我们创建了一个谓词来检查是否能被 3 或 5 整除,然后使用它来过滤一系列数字。过滤后的流仅包含匹配的值。

链接多个谓词

LongPredicate 的默认方法可以链接起来,以创建复杂的条件。这允许从简单的组件构建复杂的谓词,同时保持可读性。

Main.java
package com.zetcode;

import java.util.function.LongPredicate;

public class Main {

    public static void main(String[] args) {

        LongPredicate isEven = n -> n % 2 == 0;
        LongPredicate isPositive = n -> n > 0;
        LongPredicate isTwoDigits = n -> n >= 10 && n <= 99;
        
        // Chain multiple predicates
        LongPredicate complexCondition = isPositive.and(isTwoDigits).and(isEven.negate());
        
        System.out.println("25: " + complexCondition.test(25));
        System.out.println("-5: " + complexCondition.test(-5));
        System.out.println("12: " + complexCondition.test(12));
        System.out.println("99: " + complexCondition.test(99));
    }
}

此示例显示了链接多个谓词。我们检查正数、两位数、奇数。复杂的条件是通过使用 and 和 negate 操作组合更简单的谓词构建的。

实际示例:数字验证器

让我们使用 LongPredicate 创建一个实际的数字验证器。我们将结合几个验证规则来检查数字是否满足特定的业务需求。

Main.java
package com.zetcode;

import java.util.function.LongPredicate;

public class Main {

    public static void main(String[] args) {

        // Define validation rules
        LongPredicate isInAllowedRange = n -> n >= 1000 && n <= 9999;
        LongPredicate isNotForbiddenNumber = n -> n != 1234 && n != 4321;
        LongPredicate hasValidChecksum = n -> (n % 10 + n / 10 % 10) % 2 == 0;
        
        // Combine all rules
        LongPredicate isValidNumber = isInAllowedRange
            .and(isNotForbiddenNumber)
            .and(hasValidChecksum);
        
        long[] testNumbers = {1234, 5678, 9999, 4321, 2468, 1001};
        
        for (long num : testNumbers) {
            System.out.printf("%d is valid: %b%n", num, isValidNumber.test(num));
        }
    }
}

此实际示例创建了一个具有多个规则的数字验证器。数字必须是 4 位数、不被禁止并且通过校验和测试。组合后的谓词在一个操作中有效地检查所有条件。

来源

Java LongPredicate 接口文档

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

作者

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

列出所有Java教程