一、概念
1.lambda表达式:特殊的匿名内部类,语法更简洁
2.lambda表达式:允许把函数作为一个方法的参数(函数作为方法参数传递),将代码像数据一样传递
二、lambda的语法
由三部分组成:
(数据类型 变量名,数据类型 变量名)->{
方法体
}
(参数类型 参数名称):参数列表
{代码体}:方法体
->:箭头。分割参数列表和方法体
三、初体验lambda表达式
public class Test01 { public static void main(String[] args) { Runnable runnable=()->{ System.out.println("这是lambda表达式:"+Thread.currentThread().getName()); }; new Thread(runnable).start();//开启线程 } }
四、练习1
①练习无参无返回值的lambda
//练习无参返回值的Lambda public class Test03 { public static void main(String[] args) { //1.自己创建一个User接口的实现类,并创建该类的对象 User user=new UserImpl();//多态 setShow(user); //2.使用匿名内部类 User user1=new User() { @Override public void show() { System.out.println("这是user的匿名实现类"); } }; setShow(user1); System.out.println("======================================"); //3.使用Lambda表达式 User user2=()->{ System.out.println("lambda表达式"); }; setShow(user2); } public static void setShow(User user){ user.show(); } } interface User{ public void show(); } class UserImpl implements User{ @Override public void show() { System.out.println("这是User实现方法"); } }
②有参有返回值
public class Tset01 { public static void main(String[] args) { List<People> people = new ArrayList<>(); people.add(new People("zhang",12)); people.add(new People("liu",23)); people.add(new People("san",13)); //按照年龄排序 Comparator<People> comparator=new Comparator<People>() { @Override public int compare(People o1, People o2) { return o1.getAge()-o2.getAge(); } }; Collections.sort(people,comparator); System.out.println(people); Comparator<People> comparator1=(o1,o2)->{ return o1.getAge()-o2.getAge(); }; Collections.sort(people,comparator1); System.out.println(people); } } @Data @NoArgsConstructor @AllArgsConstructor class People{ private String name; private int age; }
五、lombda表达式的使用前提
①方法的参数或局部变量类型必须为接口才能使用Lambda
②接口中有且仅有一个抽象方法(需要设置@FunctionalInterface)
六、缩写版
规则:
1.小括号内的参数类型可以省略
2.如果小括号内有且仅有一个参数,则小括号可以省略
3.如果大括号内有且仅有一个语句,可以同时省略大括号,return关键字及语句分号
public class Test01 { public static void main(String[] args) { User user=(String name,int age)->{ return name+age; }; geUer(user); User user1=(name,age)->name+"--"+age;//可以省略参数的类型,以及{}和return和分号 geUer(user1); Student student=(name)->{ System.out.println("wwww"+name); }; getStudent(student); Student student1=name -> { System.out.println("jiao"+name); }; getStudent(student1); } //1.方法的参数必须是一个接口类型 //2.该接口有且仅有一个抽象方法 public static void geUer(User user){ String show = user.show("zhang", 12); System.out.println(show); } public static void getStudent(Student student){ student.print("ddddd"); } } @FunctionalInterface//防止别人在该接口中添加新的抽象方法,可以使用注解@FunctionalInterface interface User{ public String show(String name,int age); default void fun(){};//默认 } interface Student{ public void print(String name); }
七、JDK1.8后新增的哪些:
JDK1.8以前:
public interface 接口名{
//静态常量
//抽象方法
}
JDK1.8后:
public interface 接口名{
//静态常量
//抽象方法
//默认方法
//静态方法
}
①默认方法:
格式:
修饰符 default 返回类型 方法名(){}
public interface Teacher { public static final String name=""; public abstract void show(); //如果接口新增一个方法,它的所有实现类必须重写该方法,不利于接口的扩展 public abstract void print(); default void app(){}; } class User implements Teacher{ @Override public void show() { System.out.println("user重写了"); } @Override public void print() { } } class Student implements Teacher{ @Override public void show() { System.out.println("student重写了"); } @Override public void print() { } }
②静态方法
格式:
修饰符 static 返回类型 方法名(){}
静态方法的使用:
接口中的静态方法在实现类中是不能被重写的,调用的话只能通过接口类来实现:接口名.静态方法();
public interface User { public static final String a=""; public abstract void app(); public default void he(){//默认方法可以被重写。只能通过对象调用 System.out.println("默认方法he"); } public static void su(){//静态方法不能被重写,只可以通过接口名调用 System.out.println("这是接口中的静态方法"); } } class He implements User{ @Override public void app() { System.out.println("app"); } @Override public void he() { User.super.he(); } }
八、默认方法和静态方法的区别:
1.默认方法通过实例调用,静态方法通过接口名调用
2.默认方法可以被继承,实现类可以直接调用接口默认方法,也可以重写默认方法
3.静态方法不能继承,实现类不能重写接口的静态方法,只能使用接口名调用
九、函数式接口:
1.Consumer:消费型函数式接口,有参无返回值void accept(T t)
2.Funtion:函数型函数式接口,有参有返回值R apply(T t)
3.Supper:供给型函数式接口,无参有返回值T get();
4.Predicate<T> 断言型函数式接口,有参有返回值 boolean test(T t)