【函数式接口】java.util.function.Predicate

java.util.function.Predicate 是 Java 8 引入的一个函数式接口,位于 java.util.function 包中。它表示一个断言(布尔值函数),接受一个输入参数并返回一个布尔值。

核心特性

  1. 函数式接口:只有一个抽象方法
  2. 泛型支持Predicate<T> 可以处理任何类型的对象
  3. 常用场景:用于条件检查、过滤操作等

接口定义

/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package java.util.function;

import java.util.Objects;

/**
 * Represents a predicate (boolean-valued function) of one argument.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #test(Object)}.
 *
 * @param <T> the type of the input to the predicate
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);

    /**
     * Returns a composed predicate that represents a short-circuiting logical
     * AND of this predicate and another.  When evaluating the composed
     * predicate, if this predicate is {@code false}, then the {@code other}
     * predicate is not evaluated.
     *
     * <p>Any exceptions thrown during evaluation of either predicate are relayed
     * to the caller; if evaluation of this predicate throws an exception, the
     * {@code other} predicate will not be evaluated.
     *
     * @param other a predicate that will be logically-ANDed with this
     *              predicate
     * @return a composed predicate that represents the short-circuiting logical
     * AND of this predicate and the {@code other} predicate
     * @throws NullPointerException if other is null
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    /**
     * Returns a predicate that represents the logical negation of this
     * predicate.
     *
     * @return a predicate that represents the logical negation of this
     * predicate
     */
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    /**
     * Returns a composed predicate that represents a short-circuiting logical
     * OR of this predicate and another.  When evaluating the composed
     * predicate, if this predicate is {@code true}, then the {@code other}
     * predicate is not evaluated.
     *
     * <p>Any exceptions thrown during evaluation of either predicate are relayed
     * to the caller; if evaluation of this predicate throws an exception, the
     * {@code other} predicate will not be evaluated.
     *
     * @param other a predicate that will be logically-ORed with this
     *              predicate
     * @return a composed predicate that represents the short-circuiting logical
     * OR of this predicate and the {@code other} predicate
     * @throws NullPointerException if other is null
     */
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    /**
     * Returns a predicate that tests if two arguments are equal according
     * to {@link Objects#equals(Object, Object)}.
     *
     * @param <T> the type of arguments to the predicate
     * @param targetRef the object reference with which to compare for equality,
     *               which may be {@code null}
     * @return a predicate that tests if two arguments are equal according
     * to {@link Objects#equals(Object, Object)}
     */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }

    /**
     * Returns a predicate that is the negation of the supplied predicate.
     * This is accomplished by returning result of the calling
     * {@code target.negate()}.
     *
     * @param <T>     the type of arguments to the specified predicate
     * @param target  predicate to negate
     *
     * @return a predicate that negates the results of the supplied
     *         predicate
     *
     * @throws NullPointerException if target is null
     *
     * @since 11
     */
    @SuppressWarnings("unchecked")
    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return (Predicate<T>)target.negate();
    }
}


主要方法

  1. 抽象方法
    • boolean test(T t):对给定参数进行断言测试
  2. 默认方法
    • and(Predicate other):逻辑与组合
    • or(Predicate other):逻辑或组合
    • negate():逻辑非操作
  3. 静态方法
    • isEqual(Object target):创建一个测试输入是否等于目标值的谓词

使用示例

基本用法

Predicate<String> isEmpty = s -> s.isEmpty();
System.out.println(isEmpty.test("")); // true
System.out.println(isEmpty.test("Hello")); // false


方法组合

Predicate<String> isLongerThan5 = s -> s.length() > 5;
Predicate<String> startsWithA = s -> s.startsWith("A");

// 组合两个条件
Predicate<String> combined = isLongerThan5.and(startsWithA);
System.out.println(combined.test("Apple")); // false (长度不大于5)
System.out.println(combined.test("Avocado")); // true


常用场景 - 过滤集合

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");

// 使用Predicate过滤
List<String> longNames = names.stream()
    .filter(name -> name.length() > 4)
    .collect(Collectors.toList());
// 结果: ["Alice", "Charlie", "David"]


静态方法使用

List<String> words = Arrays.asList("Java", "Python", "C++", "");
Predicate<String> isJava = Predicate.isEqual("Java");
words.stream().filter(isJava).forEach(System.out::println); // 输出: Java

实际应用场景
  1. 集合过滤(Stream API 中的 filter() 方法)
  2. 条件验证
  3. 动态条件组合
  4. 作为方法参数传递条件逻辑

Predicate 接口是函数式编程在 Java 中的重要体现,它使得条件逻辑可以像对象一样被传递和组合,大大增强了代码的灵活性和可重用性。

### Java `util.function` 包功能与使用教程 #### 1. 背景介绍 自 JDK 1.8 发布以来,Java 引入了 Lambda 表达式以及支持函数式编程的相关特性。为了更好地支持这些新特性和简化开发流程,Java 提供了一个新的包——`java.util.function`[^1]。 该包主要包含了各种用于函数式编程的基础接口,它们被设计成可以作为 lambda 表达式的靶向类型(target type),从而使得开发者能够更方便地编写简洁而高效的代码[^2]。 --- #### 2. 常见接口及其用途 以下是 `java.util.function` 中一些常用的函数式接口: ##### (1) **Function<T, R>** 表示接受一个参数并返回结果的函数。此接口的主要方法是 `apply(T t)`,它会应用给定的操作于输入对象,并返回计算后的结果[^3]。 ```java import java.util.function.Function; public class Example { public static void main(String[] args) { Function<String, Integer> stringLength = s -> s.length(); System.out.println(stringLength.apply("Hello")); // 输出: 5 } } ``` ##### (2) **Predicate<T>** 代表一种布尔值判断逻辑,通常用来测试某个条件是否满足。核心方法为 `test(T t)`,如果指定的对象符合内部定义的标准,则返回 true;否则 false。 ```java import java.util.function.Predicate; public class PredicateExample { public static void main(String[] args) { Predicate<Integer> isEven = n -> n % 2 == 0; System.out.println(isEven.test(4)); // 输出: true } } ``` ##### (3) **Consumer<T>** 执行只读操作而不改变数据本身的行为模式。典型的方法有 `accept(T t)` 和默认实现的 `andThen()` 方法来组合多个消费者实例一起工作。 ```java import java.util.function.Consumer; public class ConsumerExample { public static void main(String[] args) { Consumer<String> printer = str -> System.out.print(str); printer.accept("World "); // 输出: World } } ``` ##### (4) **Supplier<T>** 提供无参调用即可获取某种类型的实例化对象的方式。它的唯一抽象方法叫做 `get()`,没有任何形参列表却总是要产生一个新的 T 类型的结果。 ```java import java.util.Random; import java.util.function.Supplier; public class SupplierExample { public static void main(String[] args) { Supplier<Double> randomValueGenerator = () -> Math.random() * 100d; double value = randomValueGenerator.get(); System.out.printf("%.2f%n",value); // 随机数输出示例 } } ``` ##### (5) **BiFunction<T,U,R>** 类似于 Function 接口但是接收两个不同类型的参数而不是单一的一个。其 apply 方法签名变为 `(T t, U u)` 形式。 ```java import java.util.function.BiFunction; public class BiFunctionExample { public static void main(String[] args){ BiFunction<Integer,Integer,Integer> adder=(a,b)-> a+b ; int sum=adder.apply(7 ,9 ); System.out.println(sum );// 输出 :16 } } ``` --- #### 3. 如何解决找不到 `java.util.function.Function` 的问题? 当遇到 “无法访问 `java.util.function.Function` 找不到 `java.util.function.Function` 的类文件”的错误提示时,可能是因为当前项目的编译器设置不兼容 JDK 1.8 或更高版本所致。可以通过修改 Maven 构建工具中的配置文件(pom.xml) 来调整源码级别(source level) 及目标字节码等级(target bytecode version)[^4]: ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> ``` --- #### 4. 总结 通过学习上述内容可知,`java.util.function` 是一个非常重要的库集合,极大地增强了 Java 对现代程序设计理念的支持程度。利用其中预置的各种功能性接口配合 lambdas 技术可以让我们的编码过程更加流畅自然. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值