前言,如果不精通lamda表达式,请观看文章https://blog.csdn.net/wwwwwww31311/article/details/113116327
一、消费者接口
经典案例代码,怎么样,懵逼不?
//结果输出为500
@Test
public void test1 () {
consumerTest(500, (x) -> System.out.println(x));
}
public void consumerTest (double money, Consumer<Double> c) {
c.accept(money);
}
那么,看一下小编自己的消费者接口模拟实现,为了使大家能够深入理解,我们都会将一个函数式接口的实现分为两步
①构造接口匿名实现类对象然后将其传入相应的方法
②分析方法内部如何运作的
/*
这是消费型接口,有参数,无返回值类型的接口。内置一个accept抽象方法
Consumer<T>:消费型接口(void accept(T t))
*/
@FunctionalInterface
interface Consumer<T>{
void accept(T data);
}
public class Test {
public void consumerTest(Double money,Consumer<Double> customer){
customer.accept(money);
}
@Test
public void test(){
//我们先创建一个Consumer接口的匿名接口实现类,然后把它当做参数传入下面的方法consumerTest
Consumer<Double> doubleConsumer = new Consumer<Double>() {
@Override
public void accept(Double money) {
System.out.println("消费者消费:" +money);
}
};
//这个方法内部再调用的是doubleConsumer.accpet
consumerTest(500.0, doubleConsumer);
//再用lamda表达式的方式就容易接受了
consumerTest(500.0,(x) -> System.out.println("消费者消费:" +x));
}
}
运行结果
二、供给者接口
令人懵逼的代码
@Test
public void test2 () {
Random ran = new Random();
List<Integer> list = supplier(10, () -> ran.nextInt(10));
for (Integer i : list) {
System.out.println(i);
}
}
public List<Integer> supplier(int sum, Supplier<Integer> sup){
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < sum; i++) {
list.add(sup.get());
}
return list;
}
小编简单翻译后的代码
/*
Supplier<Integer>:就是一个供给类型得接口,只有产出,没人输入,就是只有返回值,没有入参
Supplier<T>:供给型接口(T get())
*/
@FunctionalInterface
interface Supplier<T> {
T get();
}
public class Test {
//供给者方法实现
public List<Integer> supplier(int sum, Supplier<Integer> sup){
ArrayList<Integer> ls = new ArrayList<>();
for (int i = 0; i < sum; i++) {
ls.add(sup.get());
}
return ls;
}
@Test
public void test2(){
//我们先创建一个Supplier接口的匿名接口实现类,然后把它当做参数传入下面的方法supplier2
//suppler2和suppler1唯一看似的不同地方就是get()方法的实现形式不一样(但它们俩get函数的内容是一模一样的)
Supplier<Integer> s1 = new Supplier<Integer>() {
@Override
public Integer get() {
return new Random().nextInt(10);
}
};
List<Integer> supplier2 = supplier(10,s1);
for (Integer i : supplier2) {
System.out.print(i + " ");
}
//再看lamda表达式写法
Random random = new Random();
List<Integer> supplier = supplier(10, () -> random.nextInt(10));
for (Integer i : supplier) {
System.out.print(i + " ");
}
System.out.println();
}
}
运行结果
三、函数式接口
懵逼的写法
@Test
public void test3 () {
String s = strOperar(" asdf ", x -> x.substring(0, 2));
System.out.println(s);
String s1 = strOperar(" asdf ", x -> x.trim());
System.out.println(s1);
}
public String strOperar(String str, Function<String, String> fun) {
return fun.apply(str);
}
翻译后的写法
/*
函数型接口,输入一个类型得参数,输出一个类型得参数,当然两种类型可以一致
Function<T, R>:函数型接口(R apply(T t))
*/
@FunctionalInterface
interface Function<T, R> {
R apply(T t);
}
public class Test {
public String strOperar(String str, Function<String,String> fun){
return fun.apply(str);
}
@Test
public void test5(){
Function<String,String> fun = new Function<String, String>() {
@Override
public String apply(String s) {
return s.substring(0,2);
}
};
//s入值是“ab”,相当于将abcdfg作为参数s传入apply方法;
String s = strOperar("abcdefg",fun);
//在看一些lamda表达式的写法就不那么蒙蔽了
String s2 = strOperar("abcdefg",(str) -> str.substring(0,2));
}
}
运行结果
四、断言型接口
最后一个不再模拟,看一下标准代码
/*
Predicate<T>:断言型接口(boolean test(T t))
上面就是一个断言型接口,输入一个参数,输出一个boolean类型得返回值
用来判断是否加入集合中,这种结构非常适合做过滤器Filter
*/
public class Test {
public List<Integer> filterInt(List<Integer> list, Predicate<Integer> pre){
List<Integer> ls = new ArrayList<>();
for (Integer l : list) {
if(pre.test(l)){
ls.add(l);
}
}
return ls;
}
@org.junit.jupiter.api.Test
public void test7(){
List<Integer> ls = new ArrayList<>();
ls.add(1);
ls.add(2);
ls.add(3);
ls.add(4);
ls.add(5);
List<Integer> lists = filterInt(ls, x -> (x > 2));
for (Integer list : lists) {
System.out.print(list + " ");
}
}
}