在Java8之前,如果想”让参数具备行为能力”,即将代码块作为参数进行传递,这是很不方便的。比较普遍的方式就是创建一个类的实例对象,让实例去调用这个方法,从而达到代码块的传递。
1.函数式接口
概念:有且仅有一个抽象方法(但可以有其他方法,如:静态方法和默认方法【默认方法主要是为了拓展其实现类时可以不重写接口中的某些方法,提高可拓展性】)的接口,因为只有一个抽象方法才能确保Lambda进行顺利的推导
注解:@FunctionalInterface
// JDK内置的函数式接口 JDK1.8提供的内置函数式接口可以在java.util.function包下获
@FunctionalInterface
public interface Function {
R apply(T t);
default Function compose(Functionsuper V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default Function andThen(Functionsuper R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static Function identity() {
return t -> t;
}
}
2.Lambda
语法:类型可以省略写(因为有自动推导的功能,这也是为什么函数式接口只允许有一个抽象方法的原因),当执行语句只有一条时吗,可以将{}省略,并且将return关键字省去。除此之外,Lambda有延迟加载的功能,在某些场景下可以提升效率。
无参: ()->{ //执行语句 }
单参:(T t)->{ //执行语句 }
(t)->{ //执行语句 }
多参:(T t, K k)->{ //执行语句 }
1 /**
2 * @Created by zhenjun_gan
3 * @Date 2020/6/9
4 * 自定义函数式接口
5 */
6 @FunctionalInterface
7 public interface MyFunction {
8 void myMethod();
9 }
10
11 // 测试类
12 public class LambdaExample {
13
14 public static void main(String[] args) {
15 //传统的开启线程
16 new Thread(new Runnable() {
17 @Override
18 public void run() {
19 System.out.println("开启线程1");
20 }
21 }).start();
22 // Lambda简化
23 new Thread(() -> {
24 System.out.println("开启线程3");
25 }).start();
26
27 new Thread(() -> System.out.println("开启线程2")).start();
28
29 //使用Lambda遍历集合
30 Arrays.asList(1, 2, 2, 4, 1, 66, 3, 778, 0).forEach((num) -> System.out.println(num));
31
32 //测试函数式接口
33 int y = 12;
34 int x = 10;
35 String result1 = adder(x, y, new BiFunction() {
36 @Override
37 public Object apply(Object o, Object o2) {
38 return "" + x + y;
39 }
40 });
41 //Lambda简化
42 String result3 = adder(x, y, (a, b) -> {
43 return "" + a + b;
44 });
45 //省略 return 和{}
46 String result2 = adder(x, y, (a, b) -> "" + a + b);
47 System.out.println(result1);// 1012
48 System.out.println(result2);// 1012
49 System.out.println(result3);// 1012
50
51 // 延迟执行
52 testFunction(2, () -> System.out.println("执行function.myMethod..."));
53 }
54 //测试自定义的函数式接口
55 public static void testFunction(int a, MyFunction function) {
56 if (a == 1) {
57 System.out.println("执行testFunction...");
58 function.myMethod();
59 }
60 }
61 //做一个字符串的添加
62 public static String adder(Integer x, Integer y, BiFunction fun) {
63 return fun.apply(x, y);
64 }
65 }
Lambda例子代码
3.java8提供的常用函数式接口
Consumer
1 class Person {
2 private String name;
3 public Person(String name) {
4 this.name = name;
5 }
6 // 重写equals ...
7 //getter and setter ...
8 }
9
10 import java.util.function.Consumer;
11 import java.util.function.Function;
12 import java.util.function.Predicate;
13 import java.util.function.Supplier;
14 /**
15 * @Created by zhenjun_gan
16 * @Date 2020/6/10
17 * 常用的函数式接口
18 */
19 public class CommonFunctionLambdaExample {
20
21 public static void main(String[] args) {
22
23 Person person1 = testSupplier(() -> new Person("张三"));
24 System.out.println(person1);//Person{ name='张三'}
25
26 Person person2 = new Person("李四");
27 testConsumer(person2, person -> System.out.println(person));//Person{ name='李四'}
28
29 String name = "王五";
30 Person person3 = testFunction(name, pName -> new Person(pName));//Person{ name='王五'}
31 System.out.println(person3);
32
33 Person person = new Person("老刘");
34 Person person4 = new Person("老刘");
35 Person person5 = new Person("老王");
36 System.out.println(testPredicate(person4, p -> person.equals(p)));//true
37 System.out.println(testPredicate(person5, p -> person.equals(p)));//false
38 }
39
40 // 生产一个Person对象(生产)
41 public static Person testSupplier(Supplier supplier) {
42 return supplier.get();
43 }
44
45 // 消费一个Person对象(消费)
46 public static void testConsumer(Person person, Consumer consumer) {
47 consumer.accept(person);
48 }
49
50 //消费一个name生产一个Person(转换)
51 public static Person testFunction(String name, Function function) {
52 return function.apply(name);
53 }
54
55 //判断(断言)
56 public static boolean testPredicate(Person person, Predicate predicate) {
57 return predicate.test(person);
58 }
59 }
常用函数式接口
4.结语
java中的函数式接口其实单独使用并没有什么太大的意义,只是相比于传统的代码简化了而已,但是也降低了代码的可读性。Java中使用Lambda主要是为了与Stream结合,在实际工作中也是与Stream结合对数据进行一些操作,与传统的数据集操作相比更具优雅性,同时效率也更高。
Original: https://www.cnblogs.com/zhenjungan/p/13080904.html
Author: zhenjungan
Title: Java学习笔记_Lambda学习
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581884/
转载文章受原作者版权保护。转载请注明原作者出处!