Java Consumer接口

Java Consumer接口,用户希望编写实现 java.util.function.Consumer 包的 lambda 表达式,可以使用 lambda 表达式或方法引用来实现 void accept(T t) 方法。例 2-1 列出了 Consumer 接口定义的方法,其单一抽象方法为 void accept(T t)

Java Consumer接口 问题描述

用户希望编写实现 java.util.function.Consumer 包的 lambda 表达式。

Java Consumer接口 解决方案

使用 lambda 表达式或方法引用来实现 void accept(T t) 方法。

Java Consumer接口 具体实例

例 2-1 列出了 Consumer 接口定义的方法,其单一抽象方法为 void accept(T t)

例 2-1 Consumer 接口定义的方法

void accept(T t)                               ➊
default Consumer<T> andThen(Consumer<? super T> after) ➋

❶ 单一抽象方法
❷ 用于复合操作的默认方法
accept 方法传入一个泛型参数并返回 void。在所有传入 Consumer 作为参数的方法中,最常见的是 java.util.Iterable 接口的默认 forEach 方法,如例 2-2 所示。

例 2-2 Iterable 接口定义的 forEach 方法

default void forEach(Consumer<? super T> action) ➊

➊ 将可迭代集合(iterable collection)中的所有元素传递给 Consumer 参数
如例 2-3 所示,所有线性集合通过对集合中每个元素执行给定的操作来实现 Iterable 接口。

例 2-3 打印集合中的元素

List<String> strings = Arrays.asList("this", "is", "a", "list", "of", "strings");

strings.forEach(new Consumer<String>() {      ➊
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
});

strings.forEach(s -> System.out.println(s));  ➋
strings.forEach(System.out::println);         ➌

❶ 匿名内部类实现
❷ lambda 表达式
❸ 方法引用
在本例中,由于 accept 方法只传入一个参数且不返回任何值,其签名与 lambda 表达式相符。通过 System.out 访问 PrintStream 类的 println 方法,它与 Consumer 相互兼容。因此,最后两条语句都可以作为 Consumer 参数的目标。
如表 2-1 所示,java.util.function 包还定义了三种 Consumer<T> 的基本变体,以及一种双参数形式。
表2-1:其他Consumer接口

接口 单一抽象方法
IntConsumer void accept(int x)
DoubleConsumer void accept(double x)
LongConsumer void accept(long x)
BiConsumer void accept(T t, U u)

Consumer 接口期望执行带有副作用的操作(即它可能会改变输入参数的内部状态),参见范例 Predicate接口

BiConsumer 接口的 accept 方法传入两个泛型参数,这两个泛型参数应为不同的类型。java.util.function 包定义了 BiConsumer 接口的三种变体,每种变体的第二个参数为基本数据类型。以 ObjIntConsumer 接口为例,其 accept 方法传入两个参数,分别为泛型参数和 int 参数。ObjLongConsumerObjDoubleConsumer 接口的定义与 ObjIntConsumer 类似。
标准库还支持 Consumer 接口的一些其他用法。
Optional.ifPresent(Consumer<? super T> consumer)
  如果值存在,则调用指定的 consumer;否则不进行任何操作。
Stream.forEach(Consumer<? super T> action)
  对流的每个元素执行操作 1Stream.forEachOrdered 方法与之类似,它根据元素的出现顺序(encounter order)访问元素。
1这项操作十分常见,因此 Iterable 接口也直接定义了 forEach 方法。当源元素不是来自集合或需要创建并行流时,Stream.forEach 方法就很有用。

Stream.peek(Consumer<? super T> action)
  首先执行给定操作,再返回一个与现有流包含相同元素的流。peek 方法在调试中极为有用(参见范例 利用peek方法对流进行调试)。

赞(7)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

Java 实例