Consumer 源码
package java.util.function;import java.util.Objects;@FunctionalInterface
public interface Consumer<T> {void accept(T t);default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}
}
从源码来看,Consumer函数主要有两个方法,accept和andThen。
Consumer 使用
演示一
建立演示方法:
public static void t1(){Consumer<Integer> cal=x-> {x=x*10;System.out.println(x);};cal.accept(20);}
执行结果:
200
演示二
创建一个car汽车类
/*** 汽车*/
public class Car {private String name;private String company;/*** 设置名称并返回当前对象* @param name* @return*/public Car setName(String name){this.name=name;return this;}/*** 设置公司并返回当前类* @param company* @return*/public Car setCompany(String company){this.company=company;return this;}@Overridepublic String toString() {return "name:"+name+" company:"+company;}
}
创建演示方法:
public static void t2(Consumer<Car> consumer){Car car=new Car();consumer.accept(car);System.out.println(car.toString());}public static void main(String[] args) {t2(Car->Car.setName("长安cs 85").setCompany("长安"));}
执行结果:
name:长安cs 85 company:长安
演示三
public static void t3(){Consumer<Car> setNameFn=car -> {car.setName("长城H6汽车");};Consumer<Car> setCompanyFn=car -> {car.setCompany("长城公司");};Car car1=new Car();setNameFn.accept(car1);System.out.println(car1);Car car2=new Car();//使用andThen链接多个函数执行setNameFn.andThen(setCompanyFn).accept(car2);System.out.println(car2);}
执行结果:
name:长城H6汽车 company:null
name:长城H6汽车 company:长城公司
consumer从字面上面来理解就是消费的意思,用过mq的,应该大概可以了解到意思。
我们先来看看Java8定义的这个consumer的接口:
@FunctionalInterface
public interface Consumer<T> {void accept(T t);default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}
}
该接口被@FunctionalInterface注解修饰,这个注解的意思代表的是这个接口只有一个抽象接口方法,如果超过一个,只不能不用该接口,会编译不通过。
该接口有一个抽象方法accept,接受的是泛型T的一个参数类型,这个方法是在consumer的实例显示被调用之后,那么指定的函数式表达式才会被执行,请看下面例子:
// 构造函数式表达,并赋值于consumer对象,其中此时泛型已经被指定为Integer了
// 所以此时调用accept方法时,传入的对象必须一一对应传入Integer类型
Consumer<Integer> consumer = x -> {int a = x + 2;System.out.println(a);// 12System.out.println(a + "_");// 12_};// 显示调用,consumer中的函数式方法才会调用,可以理解为预先// 定义好要执行的代码逻辑,等到要执行的时候才显示的执行,这在项目中// 的需求还是很大,比如数据还没有到达,则此时可以等到数据到达之后才调用consumer.accept(10);
该接口方法还有另外一个默认实现方法andThen,从方法名很容易知道,先执行本接口方法的accept方法,之后再执行after的accept方法,请看下面代码:
/**传入一个Consumer类型的参数,*他的泛型类型,*跟本接口是一致的T,先做本接口的accept操作,*然后在做传入的Consumer类型的参数的accept操作*/default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}
例子:
public class TestConsumer {public static void main(String[] args) {// 定义第一个consumer表达式Consumer<Integer> consumer = x -> {int a = x + 2;System.out.println(a);// 8System.out.println(a + "_");// 8_};// 定义第二个consumer表达式Consumer<Integer> after = x -> {int a = x * 2;System.out.println(a);// 12System.out.println(a + "_");// 12_};// 调用方式,先执行第一个consumer表达式,执行完之后将参数直接传递给// 后面的after表达式继续执行,这个场景可以用于相同入参不同方法先后执行顺序,consumer.andThen(after).accept(6);}
}
运行结果:
88_1212_
consumer是一个函数式接口(可以采用lambda写法),它的源码如下
@FunctionalInterface
public interface Consumer<T> {void accept(T t);default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}
}
consumer的具体的使用场景就是可以提前记录我们的某些操作,然后在后面再去执行,比如说:当我们在a方法中,需要把某些参数赋值给一个Integer类型的对象,而该对象只有在b方法才能赋值,那么我们可以在a方法中使用consumer记录我们要执行的操作,再把consumer作为参数传递到b方法执行,多种操作可以用该接口的default方法addThen来持续记录
a(int x, int y){Consumer<Integer> consumer = null;consumer = z -> z = x + 2;consumer.addThen(z -> z -= y);b(consumer);
}b(Consumer<Integer> consumer){Integer z = 0;consumer.accept(z);
}