1. 什么是lambda?
目前已知的是,有个箭头 ->
说一大段官方话,也没有任何意义
我们直接看代码:
之前我们创建线程是这样的
Runnable runnable = new Runnable() { @Override public void run() { System.out.println("run。。。。。。"); } }; runnable.run();
用lambda:
1 2 | Runnable run2 = () -> System.out.println("run。。。。。。"); run2.run(); |

是不是感觉特别离谱,看不懂
别急,还有更离谱的
很常见的一个例子,比较两个整数的大小
之前是这样写的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Comparatornew Comparator @Override public int compare(Integer o1, Integer o2) { return Integer.compare(o1, o2); } }; int compare = myCom.compare(12, 20); int compare1 = myCom.compare(20, 12); int compare2 = myCom.compare(20, 20); System.out.println(compare); System.out.println(compare1); System.out.println(compare2);} |
用lambda:
1 2 3 4 5 6 7 8 | Comparatorint compare = myCom.compare(12, 20);int compare1 = myCom.compare(20, 12);int compare2 = myCom.compare(20, 20);System.out.println(compare);System.out.println(compare1);System.out.println(compare2); |
甚至还可以这样 (这个是方法引用)
1 2 3 4 5 6 7 8 | Comparator int compare = myCom.compare(12, 20); int compare1 = myCom.compare(20, 12); int compare2 = myCom.compare(20, 20); System.out.println(compare); System.out.println(compare1); System.out.println(compare2); |
第一个数比第二个数
大 :返回 1
小:返回 -1
相等:返回 0

刚接触是不是黑人问号,这是什么玩意
很好,到这,你认识到了lambda 一个缺点,可阅读性差 ,优点 代码简洁
小结:看到 -> lambda 看到 : : 方法引用
2. lamdba 语法
-
基本语法
1. 箭头操作符 -> 或者叫做lambda 操作符
2. 箭头操作符将lambda 表达式拆分成两部分
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需执行的功能 , 即 Lambda 体
3. 语法格式
语法格式1:无参数,无返回值
-
1
() -> system.out.println("Hello Lambda")前边线程的那个例子就是
语法格式2:有一个参数 无返回值
1 | (x)-> System.out.println(x); |
若只有一个参数可以省略不写
1 | x-> System.out.println(x); |
之前的写法,没有使用lambda
1 2 3 4 5 6 7 8 | Consumernew Consumer @Override public void accept(String s) { System.out.println("输出的值:"+s); } }; consumer.accept("今天不想emo了"); |
使用lambda
1 2 3 | Consumerout.println("输出的值:"+s); consumer.accept("今天不想emo了"); |
语法格式3:有两个以上参数 ,并且lambda体有多条语句,有返回值
1 2 3 4 | Comparator System.out.println("其他语句"); return Integer.compare(o1, o2); }; |
语法格式4 lambda体中只有一条语句,return 和 大括号都可以省略不写
1 | Comparator |
有没有发现所有的参数,都没有参数类型,之前我们写函数的时候可是要带上参数类型的
语法格式5 lambda表达式参数列表的数据类型可以省略不写,因为JVM编译器通过上下文编译推断出数据类型——类型推断
4. 函数式接口
不管上面哪一种语法格式,lambda都是需要函数式接口的支持
函数式接口:接口中只有一个抽象方法的接口 称为函数式接口
可以使用一个注解@FunctionalInterface 修饰,可以检查是否是函数式接口
我们可以看看Runnable 接口 的源码
完成的接口类代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms /package java.lang;/** * The * class whose instances are intended to be executed by a thread. The * class must define a method of no arguments called * * This interface is designed to provide a common protocol for objects that * wish to execute code while they are active. For example, * * Being active simply means that a thread has been started and has not * yet been stopped. * * In addition, * active while not subclassing * * by instantiating a * as the target. In most cases, the * be used if you are only planning to override the * method and no other * This is important because classes should not be subclassed * unless the programmer intends on modifying or enhancing the fundamental * behavior of the class. * * @author Arthur van Hoff * @see java.lang.Thread * @see java.util.concurrent.Callable * @since JDK1.0 */@FunctionalInterfacepublic interface Runnable { /** * When an object implementing interface * to create a thread, starting the thread causes the object's * * thread. * * The general contract of the method * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run();} |

可以看到这里面就只有一个实现,有一个注解@FunctionalInterface ,说明它就是一个函数式接口,就可以进行lambda简写
来看 Comparator 也是一样 有@FunctionalInterface注解


这里可能就会有疑问,这边明明是有两个抽象方法,怎么是函数式接口呢?
别急 !!可以看到这边的注释, 说明这个equals 是 重写了超类 的 equals,本质上是对object 的重写,官方定义这样的抽象方法是不会被定义到 抽象接口数的 ,因此实际上只有一个抽象方法

我们自己可以试着定义 函数式接口,很简单
1 2 3 4 5 6 7 8 9 | package com.test1.demo;@FunctionalInterfacepublic interface MyFunc { void method(); } |
好了,如果,写两个抽象接口会怎样?

可以看到注解报错了,所以注解用来校验作用就在这
重申一遍,函数式接口:接口中只有一个抽象方法的接口 称为函数式接口
注解只是拿来校验的,方便我们一看就知道这是一函数式接口类,不然还得数个数,验证一下是不是只有一个
现在我也重写 equals ,可以看到并没有报错

5. java8 中内置四大核心函数式接口
-
Consumer
消费型接口
1 2 3 4 5 6 7 8 9 10 | //Consumer 消费型接口 @Test public void testConsumer() { cosumer(1000, (m) -> System.out.println("星期一" + m)); // 星期一1000.0 } public void cosumer(double m, Consumer con.accept(m); } |
-
供给型接口 supplier
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Test public void testSupplier() { Listint) (Math.random() * 100)); for (Integer integer : numList) { System.out.println(integer); //100 以内10位随机整数 } } // 需求:产生指定个数的整数放入集合中 public Listint num, Supplier Listnew ArrayList<>(); for (int i = 0; i < num; i++) { Integer integer = su.get(); list.add(integer); } return list; } |
-
Function
函数型接口
1 2 3 4 5 6 7 8 9 10 11 | @Test public void FunctioStr(){ String c = getFunction("sbjikss", str -> str.toUpperCase()); System.out.println(c); //SBJIKSS String sub = getFunction("sbjikss", str -> str.substring(2, 3)); System.out.println(sub);//j } public String getFunction( String str, Function return f.apply(str); } |
-
断言型接口 Predicate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public void tetPre(){ List"Hello","sss","xxxx","sjjss"); List for (String s : list1) { System.out.println(s); // Hello xxxx sjjss } } //需求:将满足条件字符串放入集合中 public List Listnew ArrayList<>(); for (String str : old) { if (pre.test(str)){ newList.add(str); } } return newList; } |
感谢阅读!!!
