匿名内部类可以省略单独创建一个.java文件的步骤。 // 但是匿名内部类也有他的弊端,弊端就是它语法太麻烦了. // // 匿名内部类中最关键的东西是方法(参数,方法体,返回值) // // 每个方法都有前中后三个东西。 // 1. 前: 参数 // 2. 中: 方法体 // 3. 后: 返回值 // // Runnable接口中重写的run方法,这三个东西分别是。 // 没有参数: 调用run方法不需要给这个方法任何的信息。 // 方法体: 打印语句,是这个线程要做的事情。 // 返回值: 这个方法没有返回值,方法调用完成后并不会产生任何的结果。 // // 同样的效果,使用Lambda表达式,就就要简便很多。 // () -> {} lambda表达式只需要关注参数,方法体,以及返回值。 // // Lambda表达式由三个东西组成 // 1. 一些参数。 // 2. 一个箭头 // 3. 一些语句 // // Lambda表达式的标准格式: // (参数类型 参数名) -> { // 方法体; // return 返回值; // } // // 注意: // 1. 小括号中的参数可以写一个,可以没有,也可以有多个,如果有多个使用逗号隔开就可以。 // 2. 箭头是一个运算符, 表示指向性动作。 // 3. 大括号中的方法体和我们之前学习的传统的方法体基本是一致的 // // Lambda表达式省略了面向对象中的条条框框。 // 可推导就是可省略。 // 因为Thread中有一个构造方法,这个构造方法需要Runnable接口类型的参数,所以可以推倒出来这个类型,所以可以省略new Runnable // 因为Runnable中只有一个抽象方法,所以重写的肯定是这个 方法,所以这个方法的方法声明是可以省略的。 // */ public class Demo02Runnable { public static void main(String[] args) { //单独创建一个runnable实现类,然后创建这个类的对象,并实现多线程。 Runnable r = new MyRunnable(); new Thread(r).start(); //使用匿名内部类完成多线程 new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "执行了"); } }).start(); //使用lambada表达式完成多线程, new Thread(() -> System.out.println(Thread.currentThread().getName() + "执行了") ).start();//用的省略格式 } }
/* 使用比较器排序对存放Person对象的集合按照Person对象的年龄进行升序排序。 */ public static void main(String[] args) { ArrayList<Person> list = new ArrayList<>();//创建集合 list.add(new Person(19, "fd")); list.add(new Person(9, "f")); list.add(new Person(10, "ffds")); //使用比较器排序根据年龄进行排序 Collections.sort(list, new Rule()); //使用匿名内部类 Collections.sort(list, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } }); //使用lambada表达式 Collections.sort(list, (Person o1, Person o2) -> { return o1.getAge() - o2.getAge(); }); // 使用简化版的lambda表达式 Collections.sort(list, (o1, o2) -> o1.getAge() - o2.getAge()); System.out.println("list:" + list); } }
/ Lambda省略格式。 // // 可推到就是可省略 // // Lambda表达式的标准格式: // (参数类型 参数名) -> { // 方法体; // return 返回值; // } // // 1. 小括号中的参数类型可以省略。 // 2. 如果参数只有一个,那么可以省略小括号。 // 3. 如果大括号中只有一条语句,那么不管这个方法有没有返回值,都可以省略大括号,return,以及分号. // */ public class Demo06SimpleLambada { public static void invokeMethod(MyInterface myInterface) { myInterface.method(10); } public static void main(String[] args) { // 使用Lambda标准格式,调用invokeMethod传递Lambda invokeMethod((int a) -> { System.out.println(a); }); //省略参数形式//如果参数只有一个,那么可以省略小括号 // 如果大括号中只有一条语句,那么不管这个方法有没有返回值, // 都可以省略大括号,return,以及分号 invokeMethod(a-> System.out.println(a)); } }
public class Demo07SimpleLambada { public static void method(Cook cook) { cook.makeFood(); } public static void main(String[] args) { //使用lambada表达式进行调用 //使用Lambda标准格式进行调用 method(() -> { System.out.println("使用Lambda标准格式吃饭饭, 不好吃"); }); //使用Lambda省略格式进行调用 method(() -> System.out.println("使用lanbada")); } }
Lambda表达式的使用前提: // 1. 必须有接口。并且接口中有且仅有一个需要被重写的抽象方法。 (这种接口叫做函数式接口) // 2. 必须支持上下文推导。方法参数要是接口类型。或者 使用一个接口类型的变量接收Lambda。 // // // Lambda表达式能否完全替换匿名内部类, 不能。 // 1. 匿名内部类可以是普通类,抽象类,以及接口。 Lambda表达式只支持接口。 // 2. 匿名内部类可以重写多个方法。 Lambda表达式要求只有一个方法。 // // Lambda表达式的原理和匿名内部类完全不同。 // Lambda表达式不是匿名内部类的语法糖。 // // Lambda表达式是使用的动态的字节码指令。 invokedynamic // // 匿名内部类用的是静态的字节码指定。 invokestatic invokeinterface........ //
public class Demo08Lambada { public static void method(Cook cook) { cook.makeFood(); } public static void main(String[] args) { method(() -> System.out.println("吃饭")); Cook cook = () -> { System.out.println("dasffdf"); }; System.out.println(cook); } }