函数式接口
刚接触完全不理解是个什么东西,但学了一会后有那么一点感觉这东西的好处了
对函数式接口的理解
我觉得这个东西就是为了简化代码,减轻内存压力的
如果为了使用一个方法而重新写一个类并实例化它,就会浪费内存去存储这个类
这时候,如果把这个方法变成一个函数,就可以简化代码,减少程序占的内存了
Supplier 接口
就是返回一个结果的参数
只有一个 get() 方法,用来获得结果
使用方法
1 2 3 4 5 6 7 8 9
| public static void main(String[] args) { String str = getString(()->{ return "demo"; }); System.out.println(str); } public static String getString(Supplier<String> sup){ return sup.get(); }
|
看代码有点难理解,我理解的执行过程是:
- 执行到 getString() 方法处,发现参数是一个 Supplier 接口
- 给 Supplier 接口传入一个 lambda 表达式,重写这个接口,并命名为 sup,进入函数中
- 调用 sup 的 get() 方法,返回这个结果
- 用 str 这个变量来接受这个返回结果
- 打印输出 str
Consumer 接口
接受单个输入参数并且不返回结果的操作,大概表示用一个传入的参数
有两个方法 accept 和 andThen
使用方法:
1 2 3 4 5 6 7 8
| public static void main(String[] args) { method("fuck me",(String str)->{ System.out.println("I say: "+ str); }); } public static void method(String name, Consumer<String> con){ con.accept(name); }
|
执行流程和 Supplier 一样,都是重写了接口
andThen 方法就是可以一次可以使用多个 Consumer 接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public static void main(String[] args) { String[] arr = {"buang,18", "kuang,20", "muang,17"}; method(arr, (mess)->{ System.out.print("姓名: " + mess.split(",")[0]); }, (mess)->{ System.out.println("年龄: " + mess.split(",")[1]); } ); } public static void method(String[] arr, Consumer<String> con1, Consumer<String> con2){ for (String message : arr) { con1.andThen(con2).accept(message); } }
|
Predicate 接口
对给定的参数进行判断,并返回一个 boolean 值
基本的方法有 test,and(并且),or(或者),negate(取反)
使用方法
1 2 3 4 5 6 7 8 9 10
| public static void main(String[] args) { String str = "abc"; boolean b =check(str,(str1)->{ return str1.length()>5; }); System.out.println(b); } public static boolean check(String str, Predicate<String> pre){ return pre.test(str); }
|
对一 Predicate 接口的理解
- 执行到 check() 方法处,传入一个字符串,发现要传入一个 Predicate 的接口实现
- 重写 Predicate 的 test() 方法,可以使用 lambda 表达式
- 重写 test() 方法的判断标准是字符串长度大于5,由于 “abc” 长度小于5,返回 false
- 输出 false 这个结果
and 方法就是要两边都满足才判断为真,需要传入多个 Predicate 接口实现
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public static void main(String[] args) { String s = "abandon"; boolean b = method(s, (str)->{ return str.length()>5; },(str)->{ return str.contains("a"); }); System.out.println(b); } public static boolean method(String str, Predicate<String> pre1, Predicate<String> pre2){ return pre1.and(pre1).test(str); }
|
or 就是或,使用方法和 and 一样
1
| return pre1.or(pre1).test(str);
|
negate 就是取反,非
1
| return pre.negate().test(str);
|
Function 接口
接受一个参数并产生结果的函数
常用方法为 apply 和 andThen
使用方法
1 2 3 4 5 6 7 8 9 10
| public static void main(String[] args) { String str = "123456"; int result = method(str, (s)->{ return Integer.parseInt(s + 100); }); System.out.println(result); } public static int method(String str, Function<String, Integer> fun){ return fun.apply(str); }
|
method() 方法功能为传入一个数字字符串,经过一系列处理后,返回一个结果
andThen 方法的使用同 Consumer
1 2 3 4 5 6 7 8 9 10 11 12
| public static void change(String str, Function<String, Integer> fun1, Function<Integer, String> fun2){ String ss = fun1.andThen(fun2).apply(str); System.out.println(ss); } public static void main(String[] args) { String str = "12345678"; change(str, (s)->{ return Integer.parseInt(s) + 10; },(i)->{ return i + ""; }); }
|
change() 方法为传入一个字符串,将其转换为数字,并加10,再转换会字符串,并返回
定义函数式接口
定义一个接口,并宣称这是一个函数式接口,就是在最前面加上 @FunctionalInterface
1 2 3 4
| @FunctionalInterface public interface PrintStr { void print(String s); }
|
实例:
1 2 3 4 5 6 7 8 9
| public static void method(PrintStr p){ p.print("hello world"); }
public static void main(String[] args) { method((a)->{ System.out.println(a); }); }
|
对执行步骤的理解:
- 执行主方法,发现 method 方法需要传入一个接口实现对象
- 传入一个 lambda 表达式,参数为a,这个 a 就是 print 方法的参数
- lambda 表达式就是接口的实现对象,也就是 method 中定义的参数 p
- p 调用接口的抽象方法 print 方法
- 重写了 print 方法为输出参数 a,也就是 method 中传入 print 方法的字符串
- 打印出字符串
在执行的过程中 a=”hello world”,传入的 lambda 表达式=p
1 2 3 4 5 6 7 8 9 10
| public static void method(PrintStr p){ p.print("hello world"); }
public static void main(String[] args) { method((a)->{ a="fuck me"; System.out.println(a); }); }
|
这里就是修改了参数 a 的值,重写了传入 print 方法的参数,这样就会打印 fuck me 了
感觉这个知识点会变成这样:
什么玩意?-> 有点懂了 -> 原来如此 -> 一段时间后 -> 什么玩意?
这个东西确实说难不难,理解起来也不难,但就是脑子转不过弯来,以后肯定会多次重新学习这个东西的
感觉这个也是一个在实际使用中很有用的玩意