【JavaSE】Lambda表达式、接口组成更新、方法引用
文章目录
- 1. Lambda表达式
- 1.1 Lambda表达式初体验
- 1.2 Lambda表达式的基本格式
- 1.3 Lambda表达式练习
- 1.4 Lambda表达式的省略规则
- 1.5 Lambda表达式的注意事项
- 1.6 Lambda表达式和匿名内部类的区别
- 2. 接口组成更新
- 2.1 接口组成更新概述
- 2.2 接口中默认方法应用
- 2.3 接口中静态方法应用
- 2.4 接口中私有方法应用
- 3. 方法引用
- 3.1 方法引用初体验
- 3.2 方法引用符
- 3.3 方法引用类对象练习
- 3.4 方法引用对象的实例方法
- 3.5 方法引用类的实例方法
- 3.6 引用构造方法
1. Lambda表达式
1.1 Lambda表达式初体验
案例需求
启动一个线程,在控制台输出一句话:多线程程序启动了
实现方式一
实现步骤
定义一个类MyRunnable实现Runnable接口,重写run()方法
创建MyRunnable类的对象
创建Thread类的对象,把MyRunnable的对象作为构造参数传递
启动线程
实现方式二
匿名内部类的方式改进
实现方式三
Lambda表达式的方式改进
public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("多线程程序启动了");}
}
public class LambdaDemo {public static void main(String[] args) {//实现类的方式实现需求
// MyRunnable my = new MyRunnable();
// Thread t = new Thread(my);
// t.start();//匿名内部类的方式改进
// new Thread(new Runnable() {// @Override
// public void run() {// System.out.println("多线程程序启动了");
// }
// }).start();//Lambda表达式的方式改进new Thread( () -> {System.out.println("多线程程序启动了");} ).start();}
}
函数式编程思想概述
函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”而我们要学习的Lambda表达式就是函数式思想的体现
1.2 Lambda表达式的基本格式
1.3 Lambda表达式练习
练习一:
定义一个接口(Eatable),里面定义一个抽象方法:void eat();
定义一个测试类(EatableDemo),在测试类中提供两个方法 一个方法是:useEatable(Eatable e)
一个方法是主方法,在主方法中调用useEatable方法
public interface Eatable {void eat();
}
public class EatableImpl implements Eatable {@Overridepublic void eat() {System.out.println("一天一苹果,医生远离我");}
}
public class EatableDemo {public static void main(String[] args) {//在主方法中调用useEatable方法Eatable e = new EatableImpl();useEatable(e);//匿名内部类useEatable(new Eatable() {@Overridepublic void eat() {System.out.println("一天一苹果,医生远离我");}});//Lambda表达式useEatable(() -> {System.out.println("一天一苹果,医生远离我");});}private static void useEatable(Eatable e) {e.eat();}
}
练习二:有参有返回值抽象方法的练习
定义一个接口(Addable),里面定义一个抽象方法:int add(int x,int y);
定义一个测试类(AddableDemo),在测试类中提供两个方法 一个方法是:useAddable(Addable a)
一个方法是主方法,在主方法中调用useAddable方法
public interface Addable {int add(int x,int y);
}public class AddableDemo {public static void main(String[] args) {//在主方法中调用useAddable方法useAddable((int x,int y) -> {return x + y;
// return x - y;});}private static void useAddable(Addable a) {int sum = a.add(10, 20);System.out.println(sum);}
}
其实,lambda表达式的代码块就是抽象方法的实现 形式。
1.4 Lambda表达式的省略规则
代码演示
public interface Addable {int add(int x, int y);
}public interface Flyable {void fly(String s);
}
public class LambdaDemo {public static void main(String[] args) {// useAddable((int x,int y) -> {// return x + y;
// });//参数的类型可以省略useAddable((x, y) -> {return x + y;});//但是有多个参数的情况下,不能只省略一个
// useAddable((x,int y) -> {// return x + y;
// });// useFlyable((String s) -> {// System.out.println(s);
// });
// 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);}private static void useFlyable(Flyable f) {f.fly("风和日丽,晴空万里");}private static void useAddable(Addable a) {int sum = a.add(10, 20);System.out.println(sum);}
}
1.5 Lambda表达式的注意事项
1.6 Lambda表达式和匿名内部类的区别
2. 接口组成更新
2.1 接口组成更新概述
常量
public static final抽象方法
public abstract默认方法(Java 8)
public default 返回值类型 方法名(参数列表) { }静态方法(Java 8)
public static 返回值类型 方法名(参数列表) { }私有方法(Java 9)
private 返回值类型 方法名(参数列表) { }
2.2 接口中默认方法应用
public interface MyInterface {void show1();void show2();
}public class MyInterfaceImplOne implements MyInterface {@Overridepublic void show1() {System.out.println("One show1");}@Overridepublic void show2() {System.out.println("One show2");}
}public class MyInterfaceDemo {public static void main(String[] args) {//按照多态的方式创建对象并使用MyInterface my = new MyInterfaceImplOne();my.show1();my.show2();}
}
如果我们在接口中新增抽象方法,就必须在实现类中重写抽象方法,否则编译无法通过,有没有什么办法解决呢?
在JDK8中,引入了默认方法,如果抽线方法被设置为默认方法,就不需要在实现类中进行实现。但是,也可以在实现类中重写抽象方法。
public interface MyInterface {void show1();void show2();// void show3();// public default void show3() {// System.out.println("show3");
// }default void show3() {System.out.println("show3");}
}public class MyInterfaceDemo {public static void main(String[] args) {//按照多态的方式创建对象并使用MyInterface my = new MyInterfaceImplOne();my.show1();my.show2();my.show3();}
}
2.3 接口中静态方法应用
public interface Inter {void show();default void method(){System.out.println("Inter 中的默认方法执行了");}// public static void test(){// System.out.println("Inter 中的静态方法执行了");
// }static void test(){System.out.println("Inter 中的静态方法执行了");}
}public interface Flyable {public static void test() {System.out.println("Flyable 中的静态方法执行了");}
}public class InterImpl implements Inter,Flyable {@Overridepublic void show() {System.out.println("show方法执行了");}
}public class InterDemo {public static void main(String[] args) {//按照多态的方式创建对象并使用Inter i = new InterImpl();i.show();i.method();
// i.test();Inter.test();
// InterImpl.test();Flyable.test();}
}
2.4 接口中私有方法应用
私有方法产生原因
Java 9中新增了带方法体的私有方法,这其实在Java 8中就埋下了伏笔:Java 8允许在接口中定义带方法体的默认方法和静态方法。这样可能就会引发一个问题:当两个默认方法或者静态方法中包含一段相同的代码实
现时,程序必然考虑将这段实现代码抽取成一个共性方法,而这个共性方法是不需要让别人使用的,因此用私有给隐藏起来,这就是Java 9增加私有方法的必然性。
public interface Inter {default void show1() {System.out.println("show1开始执行");
// System.out.println("初级工程师");
// System.out.println("中级工程师");
// System.out.println("高级工程师");
// show();method();//默认方法可以调用私有的静态方法和非静态方法System.out.println("show1结束执行");}default void show2() {System.out.println("show2开始执行");
// System.out.println("初级工程师");
// System.out.println("中级工程师");
// System.out.println("高级工程师");
// show();method();System.out.println("show2结束执行");}private void show() {System.out.println("初级工程师");System.out.println("中级工程师");System.out.println("高级工程师");}static void method1() {System.out.println("method1开始执行");
// System.out.println("初级工程师");
// System.out.println("中级工程师");
// System.out.println("高级工程师");
// show();method();//静态方法只能调用静态方法,而不能调用非静态方法System.out.println("method1结束执行");}static void method2() {System.out.println("method2开始执行");
// System.out.println("初级工程师");
// System.out.println("中级工程师");
// System.out.println("高级工程师");method();System.out.println("method2结束执行");}private static void method() {System.out.println("初级工程师");System.out.println("中级工程师");System.out.println("高级工程师");}
}public class InterImpl implements Inter {}public class InterDemo {public static void main(String[] args) {//按照多态的方式创建对象并使用Inter i = new InterImpl();i.show1();System.out.println("--------");i.show2();System.out.println("--------");Inter.method1();System.out.println("--------");Inter.method2();}
}
3. 方法引用
3.1 方法引用初体验
方法引用的出现原因
在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作
那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要再写重复逻辑呢?答案肯定是没有必要
那我们又是如何使用已经存在的方案的呢?
这就是我们要讲解的方法引用,我们是通过方法引用来使用已经存在的方案
public interface Printable {void printString(String s);
}public class PrintableDemo {public static void main(String[] args) {//在主方法中调用usePrintable方法// usePrintable((String s) -> {// System.out.println(s);
// });usePrintable(s -> System.out.println(s));// System.out.println("爱生活爱Java");//方法引用符:::usePrintable(System.out::println);//可推导的就是可省略的}private static void usePrintable(Printable p) {p.printString("爱生活爱Java");}
}
3.2 方法引用符
3.3 方法引用类对象练习
将字符串转成数值输出
public interface Converter {int convert(String s);
}public class ConverterDemo {public static void main(String[] args) {//在主方法中调用useConverter方法// useConverter((String s) -> {// return Integer.parseInt(s);
// });useConverter(s -> Integer.parseInt(s));//引用类方法useConverter(Integer::parseInt);//Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数}private static void useConverter(Converter c) {int number = c.convert("666");System.out.println(number);}
}
使用说明:
Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数
3.4 方法引用对象的实例方法
public class PrintString {//把字符串参数变成大写的数据,然后在控制台输出public void printUpper(String s) {String result = s.toUpperCase();System.out.println(result);}
}public interface Printer {void printUpperCase(String s);
}public class PrinterDemo {public static void main(String[] args) {//在主方法中调用usePrinter方法// usePrinter((String s) -> { String result = s.toUpperCase();
System.out.println(result);
// System.out.println(s.toUpperCase());
// });usePrinter(s -> System.out.println(s.toUpperCase()));//引用对象的实例方法PrintString ps = new PrintString();usePrinter(ps::printUpper);//Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数}private static void usePrinter(Printer p) {p.printUpperCase("HelloWorld");}
}
使用说明:
Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数
3.5 方法引用类的实例方法
public interface MyString {String mySubString(String s,int x,int y);
}public class MyStringDemo {public static void main(String[] args) {//在主方法中调用useMyString方法// useMyString((String s,int x,int y) -> {// return s.substring(x,y);
// });useMyString((s,x,y) -> s.substring(x,y));//引用类的实例方法useMyString(String::substring);//Lambda表达式被类的实例方法替代的时候//第一个参数作为调用者//后面的参数全部传递给该方法作为参数}private static void useMyString(MyString my) {String s = my.mySubString("HelloWorld", 2, 5);System.out.println(s);}
}
Lambda表达式被类的实例方法替代的时候 第一个参数作为调用者 后面的参数全部传递给该方法作为参数
3.6 引用构造方法
public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}public interface StudentBuilder {Student build(String name,int age);
}public class StudentDemo {public static void main(String[] args) {//在主方法中调用useStudentBuilder方法// useStudentBuilder((String name,int age) -> { Student s = new Student(name,age);
return s;
// return new Student(name,age);
// });useStudentBuilder((name,age) -> new Student(name,age));//引用构造器useStudentBuilder(Student::new);//Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数}private static void useStudentBuilder(StudentBuilder sb) {Student s = sb.build("Adrian", 18);System.out.println(s.getName() + "," + s.getAge());}
}
Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数
【JavaSE】Lambda表达式、接口组成更新、方法引用相关推荐
- 十三、Java高级特性 Lambda表达式 | 接口组成更新 | 方法引用 | 函数式接口
文章目录 十三.Java高级特性 1.Lambda表达式 1.1体验Lambda表达式[理解] 1.2Lambda表达式的标准格式[理解] 1.3Lambda表达式练习1[应用] 1.4Lambda表 ...
- lambda表达式与6种方法引用格式
继JDK 1.8之后,更新了lambda的新特性 lambda是一种强调做什么,而不是用什么去做的语法 而匿名内部类则是强调如何去做,用了什么去做这件事的语法 函数式接口:有且仅有一个抽象方法的接口, ...
- Lambda表达式接口更新方法引用函数式接口Stream流
Lambda表达式&接口更新&方法引用&函数式接口&Stream流 Lambda 1.程序启动三种不同的表现形式 2.Lambda表达式的标准格式 3.练习 Lambd ...
- JavaSE Lambda 表达式
JavaSE Lambda 表达式 1. Lambda 表达式 1.1 函数式编程思想概述 1.2 体验Lambda表达式 1.3 Lambda 表达式的标准格式 1.4 Lambda 表达式的练习 ...
- Java 8 Lambda表达式-接口实现
Java 8 Lambda表达式在只有一个方法的接口实现代码编写中,可以起到简化作用: (argument list) -> body 具体看Runnable接口的例子 public class ...
- JAVA8自定义Lambda表达式的常见使用方法
根据使用场景不同,Lambda表达式的常见使用方法通常有三种写法. import org.junit.Test;/*** Lambda Test* Created by Joker on 2017/8 ...
- 利用Lambda实现通过getter/setter方法引用拿到属性名
很多开发场景需要用到Java Bean的属性名,直接写死属性名字符串的形式容易产生bug(属性名一旦变化,IDE不会告诉你你的字符串需要同步修改).JDK8的Lambda可以通过方法引用简化代码,同样 ...
- sort函数用法使用lambda表达式自定义sort排序方法
1 sort函数包含在头文件为#include<algorithm>的c++标准库中. 2 sort函数有三个参数,排序起始地址,结束地址, 排序方法(默认参数,可以不写,默认是从小到大) ...
- java8新特性之lambda表达式(及方法引用与构造器引用)
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中).使用 Lambda 表达式可以使代码变的更加简洁紧凑. 一.语法 lambda 表达式的语法格式如下: (parameters) ...
- 函数式接口、方法引用
概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口. 函数式接口,即适用于函数式编程场景的接口.而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接 ...
最新文章
- python的知识点注意事项
- 简单的TableViewCell高度自适应(只有Label,仅当参考思路)
- Google zerotouch方案介绍
- linux fedora升级操作
- flash读取程序 msp430_MSP430单片机对片内FLASH的读写操作程序范例
- 高效的企业测试-集成测试(3/6)
- 思维修炼之 第三种选择
- JavaScript:使用js脚本写入HTML代码
- 用户登陆问题,session.invalidate销毁session
- 《浪潮之巅》11~14章
- minic 动作句型处理
- 二 docker安装ca证书
- Unity跳转App的应用市场
- 前端大作业之淘宝页面设计
- 笔记本电脑分区后怎么恢复?3个方法
- 迅捷路由器造成计算机无法上网,迅捷fw325r路由器不能上网(连不上网)怎么办?...
- SVM分类,一对多;
- RESTORE 还原数据库
- python经典代码
- 常见的HTTP网络状态码汇总+HttpServletResponse源码
热门文章
- 10_07【Java】Map集合详述
- ABAP ALV(LVC)下拉框或者F4搜索帮助
- x265-1.8版本-common/wavefront.h注释
- python提取XML信息保存为txt
- SQLyog:Error Code : 1583 Incorrect parameters in the call to native function ‘concat‘
- 疯狂猜颜色小游戏C++个人项目
- 中南计算机绘图试题,中南大学计算机绘图试题b答案
- 水面无人艇局部危险避障算法研究 参考文献
- 物理机安装esxi系统
- 气压曲线软件 android,GPS气压海拔测量