文章目录
0、Consumer 用法总结
Consumer 适用于这样的场景,Consumer方法内部进行通用逻辑的处理,然后由匿名函数决定通用逻辑之后的流程,可以和策略模式相结合。需要注意的是,匿名函数是没有返回值的。
public static void main(String[] args) {
int i = 0;
if (i == 0) {
consumerTest((param) -> {
System.out.println(param);
}, "a");
} else if (i == 1) {
consumerTest((param) -> {
System.out.println(param);
}, "b");
}
}
- Consumer 作为函数的一个入参,Consumer< T>一般结合泛型
- 包含以Consumer作为参数的函数在被调用时,Consumer部分将被一个匿名函数取代
- 匿名函数是一段代码{},内部内容没有限制
- 以 Consumer 为一个参数的函数,内部每调用一次 Consumer.accept(Object),匿名函数内容就被立即执行一次,如果没有被调用,则匿名函数的内容不会执行
- Consumer.accept(Object) 中的Object 会被传递给匿名函数,一般形式为 param->{//匿名函数的逻辑}
- 可以以多个Consumer作为入参,function.andThen(function2).accept(b+“哈哈哈”);
- 匿名函数内部可以调用 以Consumer 为入参的函数,调用时,同样遵循上面的逻辑——即 【以 Consumer 为一个参数的函数,内部每调用一次 Consumer.accept(Object),匿名函数内容就被立即执行一次,如果没有被调用,则匿名函数的内容不会执行】。比如,调用函数1,函数1内部调用函数2,然后accept,.函数2内循环调用accept,运行顺序就是:函数1运行-调用函数2-函数2accept-函数2匿名函数-函数1accept-函数1匿名函数;函数2accept-函数2匿名函数-函数1accept-函数1匿名函数。
1、案例-简单(accept结果传入匿名函数)
import com.google.common.collect.Lists;
import org.apache.commons.collections4.ListUtils;
import java.util.List;
import java.util.function.Consumer;
/**
* @Title:Consumer举例子
* @Description:
* @Copyright: Copyright(c)2022
* @Author: wujie
* @Version: v1.0
* @Updatedby:
*/
public class Del {
public static void main(String[] args) {
//比如这里 param 是自定义的,表示 consumer accept 的结果
consumerBuildParam(param->function(param),"a","b");
}
public static void function(String str){
System.out.println(str);
}
/**
* Consumer 的 accept 拼装出一个参数
* @param function 任意函数,将把 consumer 的 accept 作为入参
* @param a
* @param b
*/
public static void consumerBuildParam(Consumer<String> function,
String a,
String b){
//function.accept 每调用一次,function 函数就会运行一次,当然,你也可以使用循环
function.accept(a+b);
function.accept(a+b);
}
}
2、案例-多个 Consumer(一次 accept结果 传入多个 匿名函数)
import java.util.function.Consumer;
/**
* @Title:Consumer举例子
* @Description:
* @Copyright: Copyright(c)2022
* @Author: wujie
* @Version: v1.0
* @Updatedby:
*/
public class Del {
public static void main(String[] args) {
consumerBuildParam(param->function(param),param2->function2(param2),"a");
}
public static void function(String str){
System.out.println("f1"+str);
}
public static void function2(String str){
System.out.println("f2"+str);
}
/**
* function.accept 的结果作为参数,依次传入 function1 和 function2
* function.accept 调动一次,则函数分别调用一次
* @param function
* @param function2
* @param b
*/
public static void consumerBuildParam(Consumer<String> function,
Consumer<String> function2,
String b){
//function.accept 每调用一次,function 函数就会运行一次
function.andThen(function2).accept(b+"哈哈哈");
function.andThen(function2).accept(b+"哈哈哈");
}
}
3、forEach 函数 对 Consumer 的封装[forEach(function) 与 forEach(item->function.accept(item)) 等效]
一般而言,我们需要写 consumer.accept 这一句,但是 forEach 函数提供了多态方法,支持我们直接把 consumer 对象传进去,在阅读代码时可以留意一下
- forEach(function) 与 forEach(item->function.accept(item)) 等效
- 代码
import com.google.common.collect.Lists;
import java.util.function.Consumer;
/**
* @Title:Consumer举例子
* @Description:
* @Copyright: Copyright(c)2022
* @Author: wujie
* @Version: v1.0
* @Updatedby:
*/
public class Del {
public static void main(String[] args) {
consumerBuildParam(param->function(param));
}
public static void function(String str){ System.out.println("f1"+str);
}
/**
* function.accept 的结果作为参数,依次传入 function1 和 function2
* function.accept 调动一次,则函数分别调用一次
* @param function
*/
public static void consumerBuildParam(Consumer<String> function){
//forEach 封装了 action.accept
Lists.newArrayList("aaa","bbb","ccc","ddd").stream().forEach(function);
Lists.newArrayList("aaa","bbb","ccc","ddd").stream().forEach(item->function.accept(item));
}
}
- 结果
f1aaa
f1bbb
f1ccc
f1ddd
f1aaa
f1bbb
f1ccc
f1ddd
4、Consumer 的嵌套使用
只要 调用一次 accept,就会立即执行本方法调用处的匿名函数。
本方法执行多次accept,就执行多次本方法调用处的匿名函数。
匿名函数内部执行了含Consumer的函数,则等匿名函数执行完毕,像是一个栈。
4.1、Consumer 匿名方法调用另一个含Consumer作为入参的函数
- 代码
import java.util.function.Consumer;
/**
* @Title:Consumer举例子
* @Description:
* @Copyright: Copyright(c)2022
* @Author: bestcxx
* @Version: v1.0
* @Updatedby:
*/
public class Del {
public static void main(String[] args) {
Del del = new Del();
del.function(param1 -> {
System.out.println("第一次匿名函数 param1="+param1);
del.function2(param2->{
System.out.println("第二次匿名函数,param1="+param1+";param2="+param2);
});
});
}
public void function(Consumer<Integer> inner) {
System.out.println("Del.function");
for(int i=0;i<2;i++){
System.out.println("循环 Del.function.accept");
inner.accept(i);
}
}
public void function2(Consumer<Integer> inner) {
System.out.println("Del.function2");
for(int i=0;i<2;i++){
System.out.println("循环 Del.function2.accept");
inner.accept(i);
}
}
}
- 结果
Del.function
循环 Del.function.accept
第一次匿名函数 param1=0
Del.function2
循环 Del.function2.accept
第二次匿名函数,param1=0;param2=0
循环 Del.function2.accept
第二次匿名函数,param1=0;param2=1
循环 Del.function.accept
第一次匿名函数 param1=1
Del.function2
循环 Del.function2.accept
第二次匿名函数,param1=1;param2=0
循环 Del.function2.accept
第二次匿名函数,param1=1;param2=1
4.2、子类拓展父类 Consumer &循环(实战场景)
子类函数调用父类函数(super),父类函数 accept 传递给子类函数内的匿名函数,子类accept,传递给子类的匿名函数,在子类中实现了逻辑拓展
父类内部有循环 accept,则立即执行子类匿名函数,子类函数循环 accept,理解循环执行子类匿名函数,从外到内开始,从内到外扩展结束。
- 父类代码
import java.util.function.Consumer;
/**
* @Title:Consumer举例子
* @Description:
* @Copyright: Copyright(c)2022
* @Author: bestcxx
* @Version: v1.0
* @Updatedby:
*/
public class Del {
public void function(Consumer<Integer> inner) {
System.out.println("Del.function");
for(int i=0;i<2;i++){
System.out.println("循环 Del.function.accept");
inner.accept(i);
}
}
}
- 子类代码和main方法
import java.util.function.Consumer;
/**
* @Title:Consumer举例子
* @Description:
* @Copyright: Copyright(c)2022
* @Author: bestcxx
* @Updatedby:
*/
public class SubDel extends Del {
public static void main(String[] args) {
SubDel sub = new SubDel();
sub.function(param2->{
System.out.println("SubDel.main 匿名函数 param2="+param2);
});
}
@Override
public void function(Consumer<Integer> inner) {
System.out.println("SubDel.function");
super.function(innerParam->{
System.out.println("SubDel.function 匿名函数:param1="+innerParam +" SubDel.function.accept");
inner.accept(1);
});
}
}
- 结果
SubDel.function
Del.function
循环 Del.function.accept
SubDel.function 匿名函数:param1=0 SubDel.function.accept
SubDel.main 匿名函数 param2=1
循环 Del.function.accept
SubDel.function 匿名函数:param1=1 SubDel.function.accept
SubDel.main 匿名函数 param2=1
5、BiConsumer 可以构造两个参数
Consumer 每次调用 accept可以构造一个参数,然后传入到匿名函数中,
BiConsumer 每次调用 accept可以构造两个参数,然后传入到匿名函数中。
在具体使用上,大同小异。
5.1、BiConsumer 含 accept 用法举例
- 代码
import java.util.function.BiConsumer;
/**
* @Title:BiConsumer 测试BiConsumer
* @Description:
* @Copyright: Copyright(c)2022
* @Author: wujie
* @Updatedby:
*/
public class BiConsumerDel {
public static void main(String[] args) {
BiConsumerDel biConsumerDel = new BiConsumerDel();
biConsumerDel.testBiConsumer((t,u)->{
System.out.println("匿名函数逻辑");
biConsumerDel.testMethod(t,u);
}
);
}
public void testMethod(String a,Integer b){
System.out.println(String.format("a=%s,b=%d",a,b));
}
public void testBiConsumer(BiConsumer<String,Integer> biConsumer){
biConsumer.accept("aaa",111);
System.out.println("等");
biConsumer.accept("aaa",222);
}
}
- 结果
匿名函数逻辑
a=aaa,b=111
等
匿名函数逻辑
a=aaa,b=222
5.1、BiConsumer 结合 foreach 免去 accept 用法举例
Map 的 foreach 正好有俩参数,提供了静态方法,其内部封装了 accept 方法,调用时可以简写
- 代码
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.function.BiConsumer;
/**
* @Title:BiConsumer 测试BiConsumer
* @Description:
* @Copyright: Copyright(c)2022
* @Author: wujie
* @Updatedby:
*/
public class BiConsumerDel {
public static void main(String[] args) {
BiConsumerDel biConsumerDel = new BiConsumerDel();
biConsumerDel.testBiConsumer((t,u)->{
System.out.println("匿名函数逻辑");
biConsumerDel.testMethod(t,u);
}
);
}
public void testMethod(String a,Integer b){
System.out.println(String.format("a=%s,b=%d",a,b));
}
public void testBiConsumer(BiConsumer<String,Integer> biConsumer){
Map<String,Integer> map = Maps.newHashMap();
map.put("a1",1);
map.put("a2",2);
map.forEach(biConsumer);
}
}
- 结果
匿名函数逻辑
a=a1,b=1
匿名函数逻辑
a=a2,b=2
6、单独使用 Consumer\BiConsumer
这种方式,不必将Consumer\BiConsumer声明到具体名称的函数,而是可以直接在方法体中声明一个匿名函数。匿名函数的内容依旧在 accept 方法被调用时立即执行。
public static void main(String[] args) {
BiConsumer<String,String> biConsumer = (A,B)->{
System.out.println("我是匿名函数"+A+B);
};
Consumer<String> consumer = (C)->{
System.out.println("我是匿名函数"+C);
};
biConsumer.accept("a","b");
consumer.accept("c");
}
我是匿名函数ab
我是匿名函数c
25

被折叠的 条评论
为什么被折叠?



