以下博客是根据黑马视频写的Javase全集博客笔记:黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程
(一)Java语言基础
(二)Java面向对象编程
(三)Java核心类库之(常用API、字符串类、集合类、泛型)
(四) Java核心类库之(异常机制)
(五)Java核心类库之(字符集/编码集、File类、递归、IO流:字节流、字符流、特殊操作流)
(六)Java核心类库之(类加载器、反射机制、模块化)
(七)Java核心类库之(Lambda表达式)
(八)Java核心类库之(接口组成更新、方法引用、函数式接口)
(九)Java核心类库之(Stream流:生成、中间、终结、收集操作)
(十)Java核心类库之(多线程:实现多线程、线程同步)
(十一)Java核心类库之(网络编程:网络编程入门、UDP通信程序、TCP通信程序)
1 Lambda表达式
1.1 函数式编程思想概括
在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作”
面向对象思想强调“必须通过对象的形式来做事情”
函数式思想则尽量忽略面向对象的复杂语法:“强调做什么, 而不是以什么形式去做”
而我们要学习的L ambda表达式就是函数式思想的体现
体验Lambda表达式
需求:启动一个线程在控制台输出一句话线程启动了
package test; public class Demo { public static void main(String[] args) { //实现类的方式 // MyRunnable mr = new MyRunnable(); // Thread t = new Thread(mr); // t.start(); //多线程程序启动 //匿名内部类改进 // new Thread(new Runnable() { // @Override // public void run() { // System.out.println("多线程程序启动"); //多线程程序启动 // } // }).start(); //Lambda表达式改进 new Thread( () ->{ System.out.println("多线程程序启动"); //多线程程序启动 }).start(); } }
1.2 Lambda表达式标准格式
组成Lambda表达式的三要素:形式参数,箭头,代码块
Lambda表达式的格式
格式:(形式参数) -> {代码块}
形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
->:由英文中画线和大于符号组成,固定写法。代表指向动作
代码块: 是我们具体要做的事情,也就是以前我们写的方法体内容
1.3 Lambda表达式练习1(抽象方法无参无返回值)
Lambda表达式使用提前:
有一个接口
接口中有且只有一个抽象方法
接口
package test; public interface Eatable { void eat(); }
测试:
package test; public class Demo { public static void main(String[] args) { useEatable(()->{ System.out.println("吃苹果"); //吃苹果 }); } private static void useEatable(Eatable e) { e.eat(); } }
1.4 Lambda表达式练习2(抽象方法带参无返回值)
测试类
package test; public class Demo { public static void main(String[] args) { //匿名内部类 useFLyable(new FLyable() { @Override public void fly(String s) { System.out.println(s); System.out.println("飞机也在飞"); // 鸟在飞 // 飞机也在飞 } }); //Lambda表达式 useFLyable((String s)->{ System.out.println(s); System.out.println("飞机也在飞"); // 鸟在飞 // 飞机也在飞 }); } private static void useFLyable(FLyable f) { a.fly("鸟在飞"); } }
1.5 Lambda表达式练习2(抽象方法带参带返回值)
测试类
package test; public class Demo { public static void main(String[] args) { useAddable((int x,int y)->{ return x + y; //30 // return x -y ; //-10 }); } private static void useAddable(Addable a) { int sum = a.add(10, 20); System.out.println(sum); } }
1.5 Lambda表达式省略模式
省略规则:
参数类型可以省略。 但是有多个参数的情况下,不能只省略一个
如果参数有且仅有一个,那么小括号可以省略
如果代码块的语句只有一条,可以省略大括号和分号,甚至是returm
范例
package test; public class Demo { public static void main(String[] args) { //参数类型可以省略 useAddable((x,y) -> { return x + y; //30 }); //有多个参数的时候不能只省略一个 // useAddable((x,int y)->{ //y报错 // return x + y; // }); // useFLyable((s)->{ // System.out.println(s); //鸟在飞 // }); //如果参数只有一个小括号也可以省略 useFLyable(s ->{ System.out.println(s); //鸟在飞 }); //如果代码块语句只有一条,可以省略大括号和分号 useFLyable(s -> System.out.println(s));//鸟在飞 //如果代码块语句只有一条,可以省略大括号和分号;如果有return,return也要省略 useAddable((x,y) -> x + y); //30 } private static void useAddable(Addable a) { int sum = a.add(10, 20); System.out.println(sum); } private static void useFLyable(FLyable f) { f.fly("鸟在飞"); } }
1.6 Lambda表达式注意事项
使用Lambda必须要有接口, 并且要求接口中有且仅有一个抽象方法
必须有上下文环境,才能推导出Lambda对应的接口
根据局部变量的赋值得知ambda对应的接口: Runnable r= () -> System.out.printn("Lambda表达式");
根据调用方法的参数得知Lambda对应的接口: new Thread( -> System.out.printn("Lambda表达式).start();
范例
package test; public class InterDemo { public static void main(String[] args) { // useInter(()->{ // System.out.println("好好学习"); //好好学习 // }); //使用Lambda表达式必须要有接口,接口中只能有一个抽象方法 useInter(()-> System.out.println("好好学习")); //必须有上下文环境,才能推导出Lambda对应的接口 // new Thread(new Runnable() { // @Override // public void run() { // System.out.println("匿名内部类"); // } // }).start(); // Runnable r = () -> System.out.println("Lambda表达式"); // new Thread(r).start(); //Lambda表达式 new Thread(() -> System.out.println("Lambda表达式")).start(); //Lambda表达式 } private static void useInter(Inter i) { i.show(); } }
1.7 Lambda表达式和匿名内部类的区别
所需类型不同
匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
Lambda表达式:只能是接口
使用限制不同
如果接口中有且仅有一个抽象方法, 可以使用Lambda表达式,也可以使用匿名内部类
如果接口中多个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
实现原理不同
匿名内部类:编译之后,产生一个单独的.class字节码文件(占空间)
Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成