• Java 中的 Lambda 表达式


    Lambda表达式

      Lambda 表达式是 JDK1.8 的一个新特性,又称特殊的匿名内部类,可以取代大部分的匿名内部类,语法更简洁,可以写出更优雅的 Java 代码,可以极大地优化代码结构。

      Lambda 表达式不会生成单独的内部类文件,但匿名内部类会。


    Lambda表达式特性

      ★ Lambda 表达式没有显示的方法名。

      ★ Lambda 表达式很像一个函数,具有参数列表、函数体、返回类型、异常,但没有函数名。

      ★ Lambda 表达式可以作为方法的参数,也可以作为变量存储。

      ★ Lambda 表达式的代码更加简洁和精确。


    Lambda表达式的定义

    基本语法:

      <函数式接口>  <变量名> = (参数1, 参数2...) -> {

        //方法体

      };

      或

      <函数式接口>  <变量名> = (参数1, 参数2...) -> 表达式;

    注意事项:

      ✔ Lambda 表达式由三部分构成:参数列表、箭头(->)、Lambda 体。

      ✔ Lambda 体,可以是一个表达式,也可以是一个语句块。

      ✔ Lambda 体,表达式中不能加入 return 语句,因为在表达式中已经隐含了 return 语句;但是,语句块中没有隐含,需要使用 return 语句。

      ✔ Lambda 表达式并不是对所有接口都可以实现,接口需要满足一个条件才能被Lambda 表达式实现:Lambda 规定接口中只能有一个需要被实现的方法。注意,并不是规定接口中只能有一个方法。

    特别提醒:

        jdk1.8 中的另一个新特性:default,被 default 修饰的方法会有默认实现,不是必须被实现的方法。在实现Lambda 表达式的时候需注意。


    Lambda 表达式的使用

    1.无参,有返回值

    @FunctionalInterface        
    public interface LambdaTest {
        // 无参,有返回值
        int method();
    }
    public class test {
    
        public static void main(String[] args) {
            
            LambdaTest test = ()-> 20;
            
            int result = test.method();
            
            System.out.println(result);
        }
    }

    @FunctionalInterface注解:

      修饰函数式接口的,要求接口中的抽象方法只有一个。这个注解往往和 lambda 表达式一起出现。

    2.无参,无返回值

    @FunctionalInterface        
    public interface LambdaTest {
        // 无参,无返回值
        void method();
    }
    public class test {
    
        public static void main(String[] args) {
            
            LambdaTest test = () -> {};
            
            test.method();
            
        }
    }

    3.单参,有返回值

    @FunctionalInterface        
    public interface LambdaTest {
        // 单参,有返回值
        int method(int a);
    }
    public class test {
    
        public static void main(String[] args) {
            
            // 表达式形式
            LambdaTest test = a -> a+10;
            
            System.out.println(test.method(10));
            
            // 代码块形式
            LambdaTest test2 = a -> {
                return a+10;
            };
            
            System.out.println(test2.method(10));
        }
    }

    4.多参,有返回值

    @FunctionalInterface        
    public interface LambdaTest {
        // 多参,有返回值
        int method(String a, String b);
    }
    public class test {
    
        public static void main(String[] args) {
            
            // 表达式形式
            LambdaTest test = (a, b) -> a.length() - b.length();
            
            System.out.println(test.method("abb", "bbccdd"));
            
            // 代码块形式
            LambdaTest test2 = (a, b) -> {
                return a.length() - b.length();
            };
            
            System.out.println(test2.method("abb", "bbccdd"));
        }
    }

    表达式使用技巧总结

      ★ 形参列表的数据类型会自动判断。

      ★ 如果形参列表为空,只需保留()。

      ★ 如果形参只有一个,()可以省略,只需要参数的名称即可。

      ★ 如果执行语句只有一句,且无返回值,则{}可省略;如果有返回值,若想省略{},则必须同时省略return,且执行语句也必须保证只有一句。


    Lambda 表达式应用

    方法引用

      有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以可以利用 lambda表达式的接口快速指向一个已经被实现的方法。

    引用语法:

    方法归属者::方法名

    静态方法的归属者为类名,普通方法归属者为对象。

    常见形式:

    对象 :: 实例方法
      类 :: 静态方法
      类 :: 实例方法
      类 :: new

    引用要求:

      ① 参数数量和类型要与接口中定义的一致。

      ② 返回值类型要与接口中定义的一致。

    代码示例:

    public class MethodReferences {
        public static void main(String[] args) {
            // 1.对象::实例方法
            Consumer<String> consumer = s->System.out.println(s);
            consumer.accept("hello");
            
            Consumer<String> consumer2 = System.out::println;
            consumer2.accept("world");
            
            // 2.类::静态方法
            Comparator<Integer> com = (o1, o2)->Integer.compare(o1, o2);
            Comparator<Integer> com2 = Integer::compare;
                
            // 3.类::实例方法
            Function<String, String> function = e->e.toUpperCase();
            Function<String, String> function2 = String::toUpperCase;
            System.out.println(function2.apply("hello"));
            
            // 4.类::new
            Supplier<String> supplier = ()->new String();
            Supplier<String> supplier2 = String::new;
            System.out.println(supplier2.toString());
        }
    }

    创建线程

    public class TestLambda {
        public static void main(String[] args) {
            // 匿名内部类
            Runnable runnable = new Runnable() {
                
                @Override
                public void run() {
                    System.out.println("子程序执行。。。");
                }
            };
            
            // Lambda表达式
            Runnable runnable2 = ()->System.out.println("子程序执行2。。。");
            new Thread(runnable2).start();
    new Thread(()->System.out.println("子程序执行3。。。")).start(); } }

    集合操作

      可以调用集合的 public void forEach(Consumer<? super E> action) 方法,通过 Lambda 表达式的方式遍历集合中的元素。Consumer 接口是 jdk 为我们提供的一个函数式接口。

    public class test {
    
        // 集合遍历
        public static void main(String[] args) {
            ArrayList<Integer> list = new ArrayList<>();
    
            Collections.addAll(list, 4, 3, 9, 0, 5);
    
            // 方法引用
            list.forEach(System.out::println);
    
            // Lambda表达式
            list.forEach(element -> {
                if (element % 2 == 0) {
                    System.out.println(element);
                }
            });
        }
    }
    public class test {
    
        // 集合排序
        public static void main(String[] args) {
            ArrayList<Integer> list = new ArrayList<>();
    
            Collections.addAll(list, 4, 3, 9, 0, 5);
    
            // 匿名内部类
            list.sort(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1 - o2;
                }
                
            });        
    
            // lambda表达式
            list.sort((o1,o2)->o1-o2);
            
            list.forEach(System.out::println);
        }
    }
  • 相关阅读:
    初始化和实例化对象
    java设计模式
    构造方法的访问级别
    C#连接操作sqlite
    using三种用法
    C#获取当前日期时间
    C#生成excel到其他电脑生成报表时报错
    [Python] VSCode隐藏__pycache__文件夹
    [Git] 常用操作速查
    [Pytorch] 卷积尺寸计算
  • 原文地址:https://www.cnblogs.com/ruoli-0/p/13872362.html
Copyright © 2020-2023  润新知