Java基础15(Lambda表达式)

Lambda表达式

体验Lambda表达式
public class LambdaDemo {
    public static void main(String[] args) {
        //方式一:新建类实现Runnable接口
        Runnable runnable = new RunnableImpl();
        Thread thread = new Thread(runnable);
        thread.start();
        //方式二:匿名内部类
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("多线程启动");
            }
        }).start();
        //方式三:Lambda表达式
        new Thread(() -> {
            System.out.println("多线程启动");
        }).start();
    }
}
Lambda表达式的标准格式
  • ():形式参数,如果有多个参数,使用英文逗号隔开,如果没有参数,留空即可。
  • ->:固定写法,代表指向动作
  • {}:代码块,具体要做的事,方法体内容
Lambda表达式的使用前提
  • 有一个接口
  • 接口中有且只有一个抽象方法
  • 必须要有上下文环境,才能推导出对应的接口
  • 可以根据局部变量的数值推导出Lambda对应的接口:Runnable r = () -> System.out.println("Lambda表达式");new Thread(r);
  • 可以根据调用方法的参数推导出Lambda对应的接口:new Thread(() -> System.out.println("Lambda表达式")).start();
带参数,带返回值的Lambda表达式
public class AddableDemo {
    public static void main(String[] args) {
        //lambda表达式
        useAddable((x,y) -> x + y);
    }

    private static void useAddable(Addable addable) {
        System.out.println(addable.add(6,5));  
    }
    /*public interface Addable {
    int add(int x ,int y);
    }*/
}
Lambda表达式的省略模式
  • 参数的数据类型可以省略,但是有多个参数时,不能只省略一个参数的数据类型
  • 如果参数有且仅有一个,那么小括号可以省略
  • 如果代码块只有一条语句,那么可以省略大括号和分号,甚至是return
//lambda表达式
        useAddable((int x,int y) -> {
            return x + y;
        });
        //lambda表达式的省略模式
        useAddable((x,y) -> x + y);
    }
Lambda表达式和匿名内部类的区别

所需类型不同:

  • 匿名内部类:可以是接口,可以是抽象类,可以是具体类
  • Lambda表达式:只能是接口
    使用限制不同:
  • 如果接口中有且只有一个抽象方法,那么既可以使用匿名内部类也可以使用Lambda表达式
  • 如果接口中不只一个抽象方法,那么只能使用匿名内部类不能Lambda表达式
    实现原理不同:
  • 匿名内部类:编译之后产生一个单独的.class字节码文件。
  • Lambda表达式:编译之后没有一个单独的.class字节码文件。对应的字节码会在运行时动态生成。

接口组成更新描述

接口的组成

  • 常量,public static final 数据类型 变量名;
  • 抽象方法,public abstract 返回值类型 方法名 ();
  • 默认方法(Java8)
  • 静态方法(Java8)
  • 私有方法(Java9)
接口中的默认方法

格式:public default 返回值类型 方法名(参数列表){方法体}
注意事项:

  • 常用于接口升级,需要新增方法时。以及函数拼接。
  • 定义默认方法时,可以省略掉public修饰符,不能省略掉default修饰符。
  • 默认方法不是抽象方法,所以不强制被重写。可以可以被重写,重写时要去掉default关键字
接口中的静态方法

格式:public static 返回值类型 方法名(参数列表){方法体}
注意事项:

  • 不需要实例化,直接使用,节省空间
  • 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
  • public可以省略,static不能省略
接口中的私有方法

格式:

  • 格式1: private 返回值类型 方法名(参数列表){方法体}

  • 格式2:private static 返回值类型 方法名(参数列表){方法体}
    注意事项:

  • 默认方法可以调用私有的静态方法和非静态方法

  • 静态方法只能调用私有的静态方法

    方法引用符

::该符号为引用运算符,而它所在的表达式被称为方法引用

  • Lambda表达式:usePrintable(s -> System.out.println(s));,分析:拿到参数s之后通过Lambda表达式,传递给System.out.println方法处理
  • 方法引用:usePrintable(System.out::println);,分析:直接使用System.out中的println方法来取代Lambda表达式,代码更简洁
  • 获取对象::调用方法;

推导与省略

  • 如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无需指定的重载形式,他们都将被自动推导
  • 如果使用方法引用,也是同样可以根据上下文进行推导
  • 方法引用是Lambda的孪生兄弟
public class PrintableDemo {
    public static void main(String[] args) {
        //Lambda表达式
        usePrintable(i -> System.out.println(i));//999
        //方法引用
        usePrintable(System.out::println);//999
    }

    private static void usePrintable(Printable printable) {
        printable.print(999);
    }
}

Lambda表达式支持的方法引用

引用类方法
  • 格式:类名::静态方法
  • 范例:Inteager::parseInt
public class ConvertableDemo {
    public static void main(String[] args) {
        //Lambda表达式
        useConvertable((String s ) -> Integer.parseInt(s));//666
        //方法引用
        useConvertable(Integer :: parseInt);//666
        //Lambda表达式被应用类方法代替时,它的形式参数全部传递给静态方法作为参数
    }

    private static void useConvertable(Convertable convertable) {
        System.out.println(convertable.convert("666"));
    }
}
引用对象的实例方法

格式范例:

  • 创建对象:PrintUpper printUpper1 = new PrintUpper();
  • 引用对象的实例(成员)方法:userUpperable(printUpper1 :: printStringUpper);
public class UpperableDemo {
    public static void main(String[] args) {
        PrintUpper printUpper = new PrintUpper();
        //Lambda表达式
        userUpperable((String string) -> printUpper.printStringUpper(string));
        PrintUpper printUpper1 = new PrintUpper();
        //引用对象的实例(成员)方法
        userUpperable(printUpper1 :: printStringUpper);
        //Lambda表达式被对象的实例方法代替时,它的形式参数全部传递给该方法作为参数
    }

    private static void userUpperable(Upperable upperable) {
        upperable.toUpper("hello word");
    }
}
引用类的实例方法
  • 格式:类名::类的实例/成员方法);
  • 范例:String::substring
public static void main(String[] args) {
        //public String substring(int beginIndex, int endIndex),返回beginIndex和endIndex之间的字串
        //Lambda表达式
        useMyStringable((String s, int x,int y) -> s.substring(x,y));
        //引用类的实例方法
        useMyStringable(String::substring);
        //Lambda表达式被类的实例方法代替时,第一个形式参数作为调用者,其余的形式参数全部传递给该方法作为参数
    }

    private static void useMyStringable(MyString myString) {
        String result = myString.mySubString("hello", 1, 3);
        System.out.println(result);
    }
}
引用构造器(引用构造方法)
  • 格式:类名::new
  • 范例:Student::new
public class StudentBuildeDemo {
    public static void main(String[] args) {
        //Lambda表达式
        useStudentBuilderable((String name,int age) -> {return  new Student(name,age);});
        //引用构造器
        useStudentBuilderable(Student::new);
        //Lambda表达式被构造器代替时,它的形式参数全部传递给构造器/构造方法作为参数
    }
    private static void useStudentBuilderable(StudentBuilder studentBuilder) {
        Student student = studentBuilder.buildStudent("张三", 18);
        System.out.println(student.getName()+","+student.getAge());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值