Java Lambda表达式学习

初次写,写的不好,主要是记录自己学习的点点滴滴

Lambda表达式需要满足以下两点:

1使用Lambda必须要有接口,并且该接口类只有一个抽象方法

2必须有上下文环境,才能推导出Lambda对应的接口

  • 根据局部变量的赋值得知Lambda对应的接口
    Runnable r = () -> System.out.println(“Lambda表达式”);
  • 根据调用方法的参数得知Lambda对应的接口
    new Thread(() -> System.out.println(“Lambda表达式”)).start();

Lambda表达式的格式:

(形式参数)->{代码块}

形式参数:如果有多个参数,参数之间用逗号隔开,如果没有参数,直接留空就可以了

->: 指向动作(指向代码块)

{代码块}:是我们具体实现接口的内容;

下面我们拿一个Java API的线程来举例;

例:

   //创建一个匿名类
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名类多线程启动了");
            }
        }).start();
       
        //Lambda表达式
        new Thread(() ->{
            System.out.println("表达式-多线程启动了");
        }).start();
        
        //优化表达式
        new Thread(() -> System.out.println("优化后表达式-多线程启动了")).start();
    }

得到的结果:

匿名类多线程启动了

表达式-多线程启动了

优化后表达式-多线程启动了

带参举例:

 public static void main( String[] args ) {

        //接口带了一个参的 ,直接在表达式括号中将属性传递进去就可以了
        test(( String s ) -> {
            System.out.println(s);
        });
        //优化Lambda表达式
        test(s-> System.out.println(s));
    }

    //创建一个静态方法来运行
    public static void test( A a ) {
        a.method("天空一片云...");
    }

    interface A {
        void method( String s );
    }

Lambda表达式的省略模式

省略规则

参数类型可以省略,但是有多个参数的情况下,不能只省列一个

如果参数有且仅有一个,那么小括号可以省略,

如果代码块的语句只有一条,那么可以省略大括号和分好,如果有return关键字也必须省略掉

 public static void main( String[] args ) {
        lambdaAdd(new B() {
            @Override
            public int add( String s, String y ) {
                /*Integer s1 = Integer.valueOf(s);
                Integer s2 = Integer.valueOf(y);*/
                return Integer.valueOf(s)+Integer.valueOf(y);//可以直接优化成一句代码
            }
        });
        System.out.println("------------------");
        //用Lambda表达式优化
         lambdaAdd((s,y)->Integer.valueOf(s)+Integer.valueOf(y));
    }
    
    public static void lambdaAdd( B b ) {
        int add = b.add("100", "20");//传递2个值进去
        System.out.println(add);//得出的结果是 s+y
    }

    interface B{
        int add( String s, String y );
    }

接口更新三种方法

现在在接口中可以,添加default默认方法和,static 静态方法和private方法,从而不影响接口实现类(接口实现类不用实现接口方法,需要在去实现)

  • 常量
    public static final
  • 抽象方法
    public abstract
  • 默认方法(Java 8) default void method(){}
  • 静态方法(Java 8) static void method(){}; 静态方法必须用类名调取
  • 私有方法(Java 9):private void method(){};
    注意事项
    • 默认方法可以调用私有的静态方法和非静态方法
    • 静态方法只能调用私有的静态方法

示例:

public interface A {
    int method();
    void method1();

    default void method2() {
        System.out.println("method2.default方法实现了1");

        /*System.out.println("11111");
        System.out.println("2222");
        System.out.println("33333");*/
        sendMethod();   //重复代码块可以删除替换静态方法实现代码内容
        System.out.println("method2.default方法实现了");
    }
    default void method3() {
        /*System.out.println("11111");
        System.out.println("2222");
        System.out.println("33333");*/
        sendMethod();//重复代码块可以删除替换静态方法实现代码内容
        System.out.println("method2.default方法实现了");
    }
    default void method4() {
        /*System.out.println("11111");
        System.out.println("2222");
        System.out.println("33333");*/
        sendMethod();//重复代码块可以删除替换静态方法实现代码内容
        System.out.println("method2.default方法实现了");
    }
    static void method5() {
      /*  System.out.println("11111");
        System.out.println("2222");
        System.out.println("33333");*/
        sendMethod();//重复代码块可以删除替换静态方法实现代码内容
        System.out.println("method3.static 方法实现了");
    }
    static void method6() {
        /*System.out.println("11111");
        System.out.println("2222");
        System.out.println("33333");*/
        sendMethod();//重复代码块可以删除替换静态方法实现代码内容
        System.out.println("method3.static 方法实现了");
    }

    //如果接口中有共同的代码块可以直接用静态的方法重构
     static void sendMethod() {
        System.out.println("11111");
        System.out.println("2222");
        System.out.println("33333");
    }
}

实现类实现接口方法,也可不实现

/*
实现类可以实现新添加的接口方法,也可以不用实现,根据需求添加
 */
public class AImpl implements A {
    @Override
    public int method() {
        return 0;
    }

    @Override
    public void method1() {
        System.out.println("method1+AImpl 方法实现了");
    }

    @Override
    public void method2() {
        System.out.println("method2,default 方法重写了");
    }
}

方法引用一共有4种

方法引用的用处: 对Lambda表达式在某种情况下进行代码的优化

将Lambda表达式,改为方法引用

1.先判断Lambda表达式是否符合下面的四种情况任何一种就可以更改为方法引用

第一种:引用类方法

1.什么时候可以将lambda表达式改为引用类方法?

当Lambda表达式中类直接调用静态方法,将Lambda表达式的所有参数都传进到静态方法中.

2.使用引用类方法,参数是如何传递?

将lambda表达式中的所有参数全部传递到静态方法中

 public static void main( String[] args ) {
        //lambda表达式
        test((y -> Integer.valueOf(y)));

        //将表达式 改为引用类方法
        test(Integer::valueOf);//Integer 是类,valueOf是静态方法
    }
    //静态方法
    private static void test(Etable e) {
        int week = e.week("100");
        System.out.println(week);//结果为100
    }
    //接口
    interface Etable {
        int week(  String y );
    }

第二种引用对象方法

引用对象的实例方法,其实就引用类中的成员方法

  • 格式
    对象::成员方法

    public static void main( String[] args ) {
    //Lambda表达式
    lowTest(s -> s.toLowerCase());
    //将Lambda表达式改为引用对象方法
    ObjectMethod obj = new ObjectMethod();
    lowTest(obj::low);
    }
    //静态方法
    public static void lowTest( Etable e ) {
    e.lowMethod(“HelloWorld”);
    }
    }
    //接口
    interface Etable {
    void lowMethod( String s );
    }
    //方法类
    class ObjectMethod {
    public void low( String s ) {
    String s1 = s.toLowerCase();
    System.out.println(s1);
    }
    }

第三种引用类的方法

引用类的实例方法,其实就是引用类中的成员方法
  • 格式
    类名::成员方法
    public static void main( String[] args ) {
    //Lambda表达式
    test((s,x,y)->{
    return s.substring(x, y);
    });
    //优化Lambda表达式
    test((s,x,y)->s.substring(x,y));
    //改成引用类的实例方法
    test(String::substring);
    }

        //静态方法
        public static void test(Etable1 e) {
            //截取2-5的字符串
            String iloveJava = e.sub("IloveJava", 2, 6);
            System.out.println(iloveJava);
        }
    }
    interface Etable1{
        String sub( String name, int x, int y );
    }
    

第四种引用构造器方法

当Lambda表达式中存在创建对象,而且对象的构造方法中的参数全部来自于Lambda表达式对象

将lambda表达式中所有参数,都传递到创建对象的构造方法中

public static void main( String[] args ) {
       test((name,age)->{
         return new Student(name,age);
       });
       /*
       将表达式改为引用构造器方法
       */
       test(Student::new);
    }
    private static void test(Etable e) {
        Student s = e.week("孙悟空", 888);
        System.out.println(s.getName()+","+s.getAge());
    }
    interface Etable {
        Student week( String name ,int age);
    }
   static 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;
       }
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值