继上回讲完函数式接口后,这次来了解下消费型接口和供给型接口:即Consumer和Supplier接口;
首先从Consumer接口开始:
Comsumer:
这个接口里面有两个方法,一个叫accept,一个叫andThen;
(1)accept:
在创建一个消费型的实现类时,要传入一个泛型参数,这个泛型参数也是accept的接受参数类型,如下例代码:
public class Main {
public static void main(String[] args) {
//创建一个实现类,并实现其方法,注意这里需要指明泛型。
Test("lbwnb", new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("说得好:" + s); //说得好:lbwnb
}
});
}
//创建一个接受消费实现类的静态方法,在里卖弄直接调用里面的accept函数
public static void Test(String data,Consumer<String> consumer){
consumer.accept(data);
}
}
消费型接口有一个显然得特点:有来无回。它接受一个参数,在里面执行一些操作,执行完过后是没有返回值的。
(2)andThen:
这个方法也与Function接口的andThen相似,也就是你传入的另外一个方法的执行顺序,下面来看示例:
public class Main {
public static void main(String[] args) {
Consumer<String> consumer1=new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("小明说:"+s);
}
};
Consumer<String> consumer2=new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("小红说:"+s);
}
};
//小明说:lbwnb
//小红说:lbwnb
consumer1.andThen(consumer2).accept("lbwnb");
}
}
这个方法允许对传入的数据进行操作,但是要注意,只是对数据源进行操作,如果你的操作并不会直接或者间接改变数据源,那很遗憾,你第一个操作不会影响到操作二的数据。
Supplier:
这个接口相对来说理解就更加的简单,因为它只有一个方法:get()。这个方法没有参数传入,只有返回值,有小伙伴就疑问了,没有参数传入,那岂不是返回的数值是一个定值咯,其实不然,只要你合理运用就会有奇特的效果。
下面来看代码:
先创建一个Student类,给每个字段配上getter,setter。并且重写toString方法。
public class Student {
private String name;
private Integer age;
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
//重写toString方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
然后开始使用:
public class Main {
public static void main(String[] args) {
//创建学生列表,并添加数据。
List<Student> students=new ArrayList<>();
students.add(new Student("lbw",18));
students.add(new Student("小刚",17));
students.add(new Student("小红",26));
students.add(new Student("小川",13));
students.add(new Student("李华",19));
//调用方法--返回已成年的学生列表
Test(students).forEach(e->{
System.out.println(e);
});
}
public static List<Student> Test(List<Student> list){
Supplier<List<Student>> supplier=new Supplier<List<Student>>() {
@Override
public List<Student> get() {
//创建一个返回列表
List<Student> res= new ArrayList();
//将年龄大于等于18的加入列表
list.forEach(e->{
if(e.getAge()>=18){
res.add(e);
}
});
//返回列表
return res;
}
};
return supplier.get();
}
}
这个例子中,它主要是利用作用域特点的方式来获取外界的值(传入学生列表,对列表进行滤)。有人就问,我为啥直接不省去这个接口实现类,直接将逻辑写在里面,但是你得考虑它的万一有复杂的逻辑,或者其他需求呢。还有就是我这只是一个小demo,别较真。真的有用的,就算你不会直接用,但有些内置方法它就是要求你去传入一个Supplier实现类。
好,本次的介绍就到这儿,有啥不懂得可以评论一起探讨学习,有不正确得欢迎指正。