Predicate和Consumer的简单使用

本文深入探讨了Java中Predicate和Consumer接口的定义及应用。详细解释了Predicate.test用于条件判断,Consumer.accept则用于执行操作。通过一个具体示例,展示了如何结合两者进行高效且简洁的代码编写。

Predicate.test和Consumer.accept接口定义

@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);
------------------------------------
@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

Predicate.test用于条件判断,如果返回true,执行Consumer.accept中的修改或者执行操作

简单的使用场景,菜单表parentId自身引用,如果没有父菜单,parentId=0

        Consumer<Menu> parentConsumer = menu-> menu.setParentId(DEFAULT_PARENT_ID);
        Predicate<Menu> predicate = menu-> menu.getParentId() == null;
        if(predicate.test(menu)) parentConsumer.accept(menu);

上面这种情况其实直接写个if判断,然后直接修改就可以,但是有时候一个判断条件有时候会重复写个几次,这时候定义一个Predicate就比较好了,代码更简洁,加上变量命名,可读性更好

 

<think>好的,我现在需要回答用户关于Java中FunctionalInterfaceConsumerSupplier的用法与区别的问题。首先,我应该回忆这两个接口的基本定义用途。Consumer接口我记得是接受一个参数但不返回结果,通常用于消费数据,比如打印或者修改对象状态。而Supplier接口则是不接受参数但返回一个结果,用于提供数据,比如生成对象或获取配置。接下来,我需要确认它们的函数方法名。Consumer的方法是accept,而Supplier的是get。可能用户还会想知道如何在实际代码中使用它们,比如结合Lambda表达式或方法引用。 然后,区别方面,除了参数返回值的不同,还应该提到它们的不同应用场景Consumer更多用于处理数据流中的元素,而Supplier用于延迟计算或生成值。此外,是否需要异常处理也是一个点,比如Supplier可能抛出异常,而Consumer通常不处理异常。 用户可能还想看代码示例,所以需要准备简单的例子,比如使用Consumer遍历列表,用Supplier生成随机数。同时,可以提到Java8中的Stream API中的应用,比如forEach使用Consumer,collect使用Supplier。另外,可能需要比较其他函数式接口,比如FunctionPredicate,但用户主要问的是ConsumerSupplier,所以重点放在这两个上。最后,生成相关问题,帮助用户进一步学习,比如其他函数式接口的用法,或者性能方面的考虑。需要确保使用正确的LaTeX格式,行内公式用$...$,独立公式用$$...$$,但这里可能不太需要数学公式,所以主要注意代码块引用。引用之前提供的示例中的引用标记,但可能用户提供的引用内容不太相关,所以需要合理处理。 最后,检查回答结构是否清晰,是否有遗漏的重要点,并确保语言准确易懂,符合中文表达习惯。</think>在Java函数式编程中,`Consumer``Supplier`是两个核心函数式接口,它们的差异主要体现在数据流方向上。以下是详细对比使用指南: ### 一、Consumer接口 #### 1. 定义与特性 - 函数签名:`void accept(T t)` - 数据流向:**单向输入**型接口 - 典型场景:数据消费(如打印、存储、状态修改) - 注解要求:必须标注`@FunctionalInterface` #### 2. 代码示例 ```java // Lambda表达式实现 Consumer<String> printer = s -> System.out.println(s.toUpperCase()); printer.accept("hello"); // 输出"HELLO" // 方法引用实现 List<Integer> numbers = Arrays.asList(1,2,3); numbers.forEach(System.out::println); // 流式操作消费数据 ``` #### 3. 派生接口 - `BiConsumer<T,U>`:双参数消费 - `IntConsumer`:专用于基本类型int ### 二、Supplier接口 #### 1. 定义与特性 - 函数签名:`T get()` - 数据流向:**无输入单输出**型接口 - 典型场景:延迟计算、对象工厂、配置获取 - 线程安全:建议实现为无状态 #### 2. 代码示例 ```java // 生成随机数 Supplier<Double> randomSupplier = Math::random; System.out.println(randomSupplier.get()); // 工厂模式应用 Supplier<LocalDateTime> timeFactory = LocalDateTime::now; System.out.println(timeFactory.get()); ``` ### 三、核心差异对比 | 特性 | Consumer | Supplier | |--------------------|--------------------------|--------------------------| | 函数方法 | `accept(T)` | `T get()` | | 参数/返回值 | 有输入无输出 | 无输入有输出 | | 异常处理 | 通常不抛出检查异常 | 可包装检查异常 | | 流式应用位置 | `forEach()`终端操作 | `collect()`的容器工厂 | | 组合方法 | `andThen()`链式组合 | 无组合方法 | ### 四、设计模式应用 1. **观察者模式**:通过`Consumer`实现事件监听 ```java List<Consumer<String>> listeners = new ArrayList<>(); listeners.add(s -> saveToDB(s)); listeners.add(s -> sendNotification(s)); // 触发事件 listeners.forEach(c -> c.accept("事件数据")); ``` 2. **工厂模式**:通过`Supplier`实现对象创建 ```java Map<String, Supplier<Shape>> shapeFactories = new HashMap<>(); shapeFactories.put("circle", Circle::new); shapeFactories.put("square", Square::new); Shape circle = shapeFactories.get("circle").get(); ``` ### 五、性能注意事项 1. **对象创建开销**:频繁调用`Supplier.get()`时,考虑对象池技术 2. **闭包捕获成本**:Lambda表达式捕获外部变量会生成合成类 3. **方法引用优化**:`Class::method`比Lambda更易被JVM内联 ### 六、扩展应用场景 - **Consumer链**:使用`andThen`组合多个操作 ```java Consumer<String> pipeline = ((Consumer<String>)s -> validate(s)) .andThen(s -> encrypt(s)) .andThen(s -> transmit(s)); ``` - **Supplier延迟计算**:配合`Optional`处理空值 ```java Optional.ofNullable(config) .orElseGet(() -> loadDefaultConfig()); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值