共通
都是函数式接口(Functional Interface)。
函数式接口
就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
可以被隐式转换为lambda表达式
Consumer<T>
这个Consumer接口表示(或者定义)了对输入参数的一系列处理规则,这个操作需要有一个输入参数,就是一个没有返回值的匿名函数。
/**
* 表示接受单个输入参数但不返回结果的操作。 与大多数其他功能接口不同,consumer的操作是预期的
*/
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
// 将入参T,按照你定义的规则进行处理
void accept(T t);
/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
Consumer 内部方法
- accept方法
接收一个入参,按照定义的规则处理入参
public static void main(String[] args){
String test1 = "我";
String test2 = "你";
String test3 = "大家";
StringBuilder builderInput = new StringBuilder("我要买");
Consumer<String> consumer = (string) -> System.out.println(string+"爱中国");
consumer.accept(test1);
consumer.accept(test2);
consumer.accept(test3);
Consumer<StringBuilder> consumer2 = (builder) -> builder.append("玛莎拉蒂");
System.out.println("accept 前:"+builderInput.toString());
consumer2.accept(builderInput);
System.out.println("accept 后:"+builderInput.toString());
}
溯源可以在jdk源码中的List的foreach方法看到
// forEach方法把增强for的逻辑封装到方法体了(封装的是逻辑代码)。
// 在这段逻辑代码中,action.accept(t);代表的是消费的函数体本身
// 或者是我们写的任意代码(消费的是函数)
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
- andThen 方法
多个consumer的组合,定义的多个处理流程,链式化处理(流水线作业)。输入是一个规则,返回一个新的规则。
先判断入参的consumer是不是null;为null则抛出异常。然后执行consumer自身定义的规则,最后输入consumer的规则。
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
public static void main(String[] args) {
Consumer<StringBuilder> consumer1 = (builder)-> builder.append("->步骤1");
Consumer<StringBuilder> consumer2 = (builder)-> builder.append("->步骤2");
Consumer<StringBuilder> consumer3 = (builder)-> builder.append("->步骤3");
Consumer<StringBuilder> newConsumer = consumer1.andThen(consumer2).andThen(consumer3);
StringBuilder builder = new StringBuilder("原始原件");
newConsumer.accept(builder);
System.out.println(builder.toString());
}
BiConsumer<T,U>
和Consumer<T>唯一的区别就是接收的入参是两个
public interface BiConsumer<T, U> {
void accept(T t, U u);
default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {
Objects.requireNonNull(after);
return (l, r) -> {
accept(l, r);
after.accept(l, r);
};
}
}
参考
https://blog.csdn.net/qq_28683865/article/details/125024767
https://blog.csdn.net/qq_51741292/article/details/125622428?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-1-125622428-blog-125024767.t0_edu_mix&spm=1001.2101.3001.4242.2&utm_relevant_index=4
https://blog.csdn.net/qq_42543063/article/details/113932629?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-113932629-blog-125024767.t0_edu_mix&spm=1001.2101.3001.4242.1&utm_relevant_index=3