lambda
lambda :简化代码
lambda(λ)组成:
1.逗号隔开的参数列表(x,x,x)
2.箭头符号 ->。
3.lambda(λ)方法体。
下面是代码示例:
package lambda;
public class demo01 {
public static void test01(){
//原来的代码
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello...");
}
}).start();
}
public static void test02(){
//使用lambda表达式(把"废话"删除,剩下的就是lambda)
new Thread(
//() -> System.out.println("hello...")).start();
() -> {System.out.println("hello...");}).start();//方法体只有一句,大括号可有可无
}
public static void main(String[] args) {
test01();
test02();
}
}
以上述为例,new Thread()中是一个接口、抽象类,为了避免不能区分lambda到底在写哪个方法,所以lambda在语法上要求重写的接口、抽象类中只能有一个抽象方法;
函数式接口
查看Runnable()方法源码:
ps:查看源码快捷键Ctrl+Shift+i
@FunctionalInterface
public interface Runnable {
void run();
}
其中会有一个@FunctionalInterface标识,这个就是函数式接口。
函数式接口:标识@FunctionalInterface,有且只有一个抽象方法。
lambda重写的必须是函数式接口(或者只有一个抽象方法的抽象类)。
还有一个要注意的,即使没有标注@FunctionalInterface,但也只有一个抽象方法,也叫做函数式接口,即@FunctionalInterface可有可无,知识一个标注。
函数式接口从哪来?
●JDK自带(很多存在于package java.util.function包中)
○有参,无返回值(消费型)
@FunctionalInterface
public interface Consumer<T> {
void accept(T var1);
}
○无参,有返回值(供给型)
@FunctionalInterface
public interface Supplier<T> {
T get();
}
○有参,有返回值(函数型)
@FunctionalInterface
public interface Function<T, R> {
R apply(T var1);
}
○断言式接口
@FunctionalInterface
public interface Function<T, R> {
R apply(T var1);
}
lambda的两种表达方式
方式一
函数式接口 引用名 = lambda表达式;
Predicate pb = num -> num < 10;
第一个示例:
public static void test01(){
//boolean test (T t); Predicate中有这个方法
Predicate<Integer> pb = (num) -> {return num < 10;};
//Predicate<Integer> pb = num -> num < 10;
System.out.println(pb.test(3));
}
第二个示例:
先写一个自定义函数式接口
@FunctionalInterface
public interface MyMath {
int add(int a,int b);
}
public static void test02(){
//相当于将MyMath中的add方法进行了具体的实现
//lambda自带类型推断机制,因此参数的类型可以省略
//MyMath math = (int a,int b) -> { return a+b;};
MyMath math = (a,b) -> a + b;
System.out.println(math.add(1,2));
}
接下来是一些练习,以熟悉lambda表达方式:
package lambda;
import org.w3c.dom.ls.LSOutput;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class demo02 {
public static void test01(){
//boolean test (T t);
Predicate<Integer> pb = (num) -> {return num < 10;};
System.out.println(pb.test(3));
}
public static void test02(){
//相当于将MyMath中的add方法进行了具体的实现
MyMath math = (a,b) -> a + b;
System.out.println(math.add(1,2));
}
public static void test03(){
//void accept(T t);
Consumer <String > c = (x) -> System.out.println("吃" + x);
c.accept("苹果");
}
public static void test04(){
Supplier<Integer> supplier = () -> (int ) (Math.random()*9000+1000);
System.out.println(supplier.get());
}
public static void test05() {
Function<String , String> f = (x) -> x.toUpperCase();
System.out.println(f.apply("hello lambda"));
}
public static void main(String[] args) {
test01();
test02();
test03();
test04();
test05();
}
}
方式二
new Thread(
() -> System.out.println("hello...")
).start();
}
将lambda表达式所代表的函数式接口,作为一个方法的参数存在。
理解:方法B(方法A):函数是编程。
形式:方法(函数式接口)
示例:
public static void test06(){
String result = upper( (x) -> x.toUpperCase(),"hello");
System.out.println(result);
}
public static String upper(Function<String,String> fun ,String str){
return fun.apply(str);
}
图解:
乍一看一脸懵,多写几次感受一下就能够理解了。再练习一下:
public static void test07(){
myPredicate((x) -> x > 18 , 10);
}
public static void myPredicate(Predicate<Integer> pre , Integer num){
System.out.println(pre.test(num));
}
public static void test08(){
eat((x) -> System.out.println("吃"+ x),"苹果");
}
public static void eat(Consumer<String> e,String str){
e.accept(str);
}
public static void test09(){
add((a,b) -> a + b,1,2);
}
public static void add(MyMath math ,int a,int b){
int sum = math.add(a,b);
System.out.println(sum);
}
public static void test10(){
mySupplier(() -> (int) (Math.random()*9000+1000));
}
public static void mySupplier(Supplier<Integer> supplier ){
System.out.println(supplier.get());
}