文章目录

  • 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表达式、接口组成更新、方法引用相关推荐

  1. 十三、Java高级特性 Lambda表达式 | 接口组成更新 | 方法引用 | 函数式接口

    文章目录 十三.Java高级特性 1.Lambda表达式 1.1体验Lambda表达式[理解] 1.2Lambda表达式的标准格式[理解] 1.3Lambda表达式练习1[应用] 1.4Lambda表 ...

  2. lambda表达式与6种方法引用格式

    继JDK 1.8之后,更新了lambda的新特性 lambda是一种强调做什么,而不是用什么去做的语法 而匿名内部类则是强调如何去做,用了什么去做这件事的语法 函数式接口:有且仅有一个抽象方法的接口, ...

  3. Lambda表达式接口更新方法引用函数式接口Stream流

    Lambda表达式&接口更新&方法引用&函数式接口&Stream流 Lambda 1.程序启动三种不同的表现形式 2.Lambda表达式的标准格式 3.练习 Lambd ...

  4. JavaSE Lambda 表达式

    JavaSE Lambda 表达式 1. Lambda 表达式 1.1 函数式编程思想概述 1.2 体验Lambda表达式 1.3 Lambda 表达式的标准格式 1.4 Lambda 表达式的练习 ...

  5. Java 8 Lambda表达式-接口实现

    Java 8 Lambda表达式在只有一个方法的接口实现代码编写中,可以起到简化作用: (argument list) -> body 具体看Runnable接口的例子 public class ...

  6. JAVA8自定义Lambda表达式的常见使用方法

    根据使用场景不同,Lambda表达式的常见使用方法通常有三种写法. import org.junit.Test;/*** Lambda Test* Created by Joker on 2017/8 ...

  7. 利用Lambda实现通过getter/setter方法引用拿到属性名

    很多开发场景需要用到Java Bean的属性名,直接写死属性名字符串的形式容易产生bug(属性名一旦变化,IDE不会告诉你你的字符串需要同步修改).JDK8的Lambda可以通过方法引用简化代码,同样 ...

  8. sort函数用法使用lambda表达式自定义sort排序方法

    1 sort函数包含在头文件为#include<algorithm>的c++标准库中. 2 sort函数有三个参数,排序起始地址,结束地址, 排序方法(默认参数,可以不写,默认是从小到大) ...

  9. java8新特性之lambda表达式(及方法引用与构造器引用)

    Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中).使用 Lambda 表达式可以使代码变的更加简洁紧凑. 一.语法 lambda 表达式的语法格式如下: (parameters) ...

  10. 函数式接口、方法引用

    概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口. 函数式接口,即适用于函数式编程场景的接口.而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接 ...

最新文章

  1. python的知识点注意事项
  2. 简单的TableViewCell高度自适应(只有Label,仅当参考思路)
  3. Google zerotouch方案介绍
  4. linux fedora升级操作
  5. flash读取程序 msp430_MSP430单片机对片内FLASH的读写操作程序范例
  6. 高效的企业测试-集成测试(3/6)
  7. 思维修炼之 第三种选择
  8. JavaScript:使用js脚本写入HTML代码
  9. 用户登陆问题,session.invalidate销毁session
  10. 《浪潮之巅》11~14章
  11. minic 动作句型处理
  12. 二 docker安装ca证书
  13. Unity跳转App的应用市场
  14. 前端大作业之淘宝页面设计
  15. 笔记本电脑分区后怎么恢复?3个方法
  16. 迅捷路由器造成计算机无法上网,迅捷fw325r路由器不能上网(连不上网)怎么办?...
  17. SVM分类,一对多;
  18. RESTORE 还原数据库
  19. python经典代码
  20. 常见的HTTP网络状态码汇总+HttpServletResponse源码

热门文章

  1. 10_07【Java】Map集合详述
  2. ABAP ALV(LVC)下拉框或者F4搜索帮助
  3. x265-1.8版本-common/wavefront.h注释
  4. python提取XML信息保存为txt
  5. SQLyog:Error Code : 1583 Incorrect parameters in the call to native function ‘concat‘
  6. 疯狂猜颜色小游戏C++个人项目
  7. 中南计算机绘图试题,中南大学计算机绘图试题b答案
  8. 水面无人艇局部危险避障算法研究 参考文献
  9. 物理机安装esxi系统
  10. 气压曲线软件 android,GPS气压海拔测量