Consumer接口

本文深入解析Java中的Consumer接口,探讨其基本用法、各种变体如IntConsumer、DoubleConsumer等,以及如何通过lambda表达式、方法引用等方式实现Consumer接口。同时,文章对比了Consumer与BiConsumer接口的区别,为读者提供了丰富的代码示例。

Consumer接口,顾名思义,就是消费掉传入的一个泛型对象,不返回任何值。

1cc93103728284bbb4337062ef57c1d8088.jpg

可以看到在函数式接口Consumer中,有以下两个方法

  1. 单一抽象方法
  2. 用于复合操作的默认方法

常见的就是java.util.Iterable接口的默认方法forEach

8014e1e25a5fb963a885f9cfe2e7d1828f5.jpg

我们可以用以下的方式来实现:

  • 匿名内部类
  • lambda表达式
  • 方法引用

9f82086daa535e0d42aefc32fe44ece0506.jpg

还有我么可以用用Consumer的default方法

cfab3a3881c7d52e4a72c0d5707d8bbe2de.jpg

输出:

d637a8c0b4690a57a9a60876ddfc56676dd.jpg

 

对于Consumer接口,有好几个变体IntConsumer,DoubleConsumer,LongConsumer,处理相应类型的参数。

f84592c3219d6aa38053c0c236048581eb6.jpg

我们可以简单写个方法看看:

f8b417acb0ddbdc6ef94e5e5772f73f1f4a.jpg

当然还有ObjIntConsumer,ObjLongConsumer,ObjDoubleConsumer这样没有默认方法的那种

3dbda201052555bf18eef76887913626a96.jpg

这种我们可以多带一个参数,

1e52dd3b18d7259bef2e2a4ef20376a0be7.jpg

但是在BiConsumer中,却又是存在默认的复合方法的

518cf7c5ab87697cb6d8bc14d605ca06d8d.jpg

未完待续!!

 

 

转载于:https://my.oschina.net/u/2277632/blog/2985279

<think>我们被要求回答关于Java Consumer接口的问题,并参考了站内引用。根据引用,我们可以总结出Consumer接口的核心信息: 1. **作用**:Consumer是一个函数式接口,用于执行接收单个输入参数但不返回任何结果的操作(即带有副作用的操作)。 2. **包路径**:`java.util.function.Consumer` 3. **核心方法**:`void accept(T t)` 4. **常见用途**:集合遍历(如forEach)、对象处理、日志打印等。 5. **其他相关接口**:如BiConsumer(接收两个参数)等。 现在,我们将按照要求组织回答: - 首先解释Consumer接口的作用 - 然后给出使用示例(参考引用中的示例代码,并适当调整和补充) - 注意事项(如函数式接口的特性) - 最后生成相关问题 注意:引用中提供了多个示例代码,我们将选择几个典型的示例进行说明。</think>### Java `Consumer` 接口详解 `Consumer` 是 Java 8 引入的核心函数式接口(位于 `java.util.function` 包),用于**处理单个参数且不返回结果的操作**。其核心作用是封装带副作用的逻辑(如修改对象、打印日志等),通过参数传递实现行为抽象化[^1][^2][^4]。 #### 核心定义 ```java @FunctionalInterface public interface Consumer<T> { void accept(T t); // 接收参数 T,执行操作 } ``` #### 核心特性 | 特性 | 说明 | |--------------|----------------------------------------------------------------------| | **单参数** | 仅接收一个输入参数(泛型 `T`) | | **无返回值** | 返回类型为 `void`( `Function` 接口的关键区别)[^2] | | **副作用操作** | 通常用于修改对象状态、IO 操作等 | | **函数式接口** | 可用 Lambda 表达式或方法引用实现[^4] | --- ### 主要应用场景示例 #### 1. 集合遍历(`forEach` 方法) **场景**:简化集合元素处理逻辑 ```java List<String> cities = Arrays.asList("北京", "上海", "广州"); // 方式1: Lambda 表达式 cities.forEach(city -> System.out.println(city.toUpperCase())); // 输出: 北京 上海 广州(大写) // 方式2: 方法引用 cities.forEach(System.out::println); // 直接打印元素 ``` #### 2. 对象状态修改 **场景**:批量更新对象属性 ```java class User { String name; void setName(String name) { this.name = name; } } List<User> users = Arrays.asList(new User(), new User()); // 批量设置用户名 Consumer<User> setName = user -> user.setName("匿名用户"); users.forEach(setName); // 所有用户 name 变为 "匿名用户" ``` #### 3. 链式操作(`andThen` 组合) **场景**:组合多个 Consumer 按顺序执行 ```java Consumer<String> log = s -> System.out.println("日志: " + s); Consumer<String> save = s -> database.save(s); // 先记录日志再保存数据 Consumer<String> pipeline = log.andThen(save); pipeline.accept("用户登录"); ``` #### 4. 资源处理(自动关闭) **场景**:封装资源清理逻辑 ```java Consumer<InputStream> process = input -> { try (input) { // 自动关闭流 byte[] data = input.readAllBytes(); System.out.println("读取字节数: " + data.length); } catch (IOException e) { /* 异常处理 */ } }; process.accept(new FileInputStream("data.bin")); ``` --- ### 进阶用法 #### ✅ `Optional` 结合避免空指针 ```java Optional<String> name = Optional.ofNullable(request.getName()); name.ifPresent(n -> System.out.println("用户名: " + n)); // 仅当非空时执行 ``` #### ✅ 自定义工厂方法 ```java Consumer<String> createLogger(String level) { return msg -> { if ("DEBUG".equals(level)) System.out.println("[DEBUG] " + msg); else System.out.println("[INFO] " + msg); }; } // 使用 createLogger("DEBUG").accept("调试信息"); // 输出: [DEBUG] 调试信息 ``` --- ### 注意事项 1. **副作用管理**:明确文档说明操作是否修改外部状态[^2] 2. **异常处理**:在 `accept` 内捕获异常(函数式接口不支持抛出受检异常) 3. **性能敏感场景**:避免在循环中创建复杂 Consumer(可能产生 GC 压力) 4. **相关接口**: - `BiConsumer<T,U>`:处理两个参数 - `IntConsumer`:处理基本类型 `int`(避免装箱开销)[^3] --- ### 典型应用场景对比 | 场景 | `Consumer` 适用性 | 替代方案 | |--------------------|----------------------------|----------------------| | 集合元素处理 | ✅ 最佳选择(`forEach`) | 传统 for 循环 | | 对象流水线操作 | ✅ 链式组合(`andThen`) | 命令模式 | | 需要返回值的操作 | ❌ 不适用 | `Function` 接口 | | 条件触发操作 | ✅(结合 `Optional.ifPresent`) | if 语句 | > 通过 `Consumer` 可将行为抽象为参数,显著提升代码复用性和可读性(尤其在流式处理中)[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值