美文网首页@IT·互联网
Java中使用Lambda表达式

Java中使用Lambda表达式

作者: 澎湃i | 来源:发表于2018-09-07 16:01 被阅读15次

    在项目中突然看到同事使用了一种看不懂的语法,以前多行的代码使用这种语法往往一行就能够达到同样的效果。一查资料才知道是Lambda表达式,Java在Version8中引入了该特性。不得不说自己有太久没有主动学习过新的东西,刚好项目忙过,能够抽空学习下Lambda表达式。

    下面将由如下几个环节学习Lambda表达式:

    1. Lambda的定义
    2. Lambda的语法
    3. 如何在Java中使用
    4. Java中的内置函数型接口

    Lambda定义

    想要在Java中使用Lambda表达式,那么我们必须知道Lambda是个什么东西。简单来说,Lambda表达式就是一个匿名函数,也就是没有名称的函数

    了解了定义,那么如何书写一个Lambda表达式呢,这时他的语法就粉墨登场了。

    Lambda语法

    普通语法
    (param1,param2,...) -> {
        statement1,
        statement2,
        ...
        return statement3;
    }
    

    上面语法定义了Lambda表达式的通用语法,左边括号部分为参数,右边花括号部分为方法体,参数与方法体之间通过->进行分隔。
    如果细分又可以分为单参数和多参数:

    1. 单参数:可以省略左边括号,如:
    param -> {
        statement1,
        statement2,
        ...
        return statement3;
    }
    

    如果方法体只有一行时,甚至可以省略方法体的花括号,如:

    param -> statement
    
    1. 多参数与通用语法一致。
    方法引用、构造器引用语法
    • 方法引用
    // 实例名称::实例方法
    objectName::instanceMethod
    
    // 类名称::静态方法
    ClassName::staticMethod
    
    // 类名称::实例方法
    ClassName::instanceMethod
    

    方法引用调用者与方法之间使用::进行分隔。

    前面两种语法类似,等同于直接把Lambda表达式参数当成instanceMethod/staticMethod参数进行使用,例如:

    System.out::println 等同于 s -> System.out.println(s)

    Math::max等同于(int x, int y) -> Math.max(x,y)

    最后一种为类名称调用实例方法,等同于Lambda表达式把第一个参数作为方法调用者,后面参数作为方法参数进行使用,例如:

    Object::equals等同于(o1,o2) -> o1.equals(o2)

    • 构造器引用
    ClassName::new
    

    等同于Lambda表达式将参数作为构造器的参数使用,例如:
    BigDecimal::new等同于x -> new BigDecimal(x)

    在Java中的使用

    上面了解了Lambda表达式的语法,那么如何在Java中使用呢,下面我们将通过几个例子来进行说明。

    1. 在实际的项目中我们可能会对List进行一个排序,以前我们都是使用如下类似代码进行实现:
    List<String> strs = Arrays.asList("1","2","3","4");
    strs.sort(new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }
    });
    

    而使用Lambda表达式,则代码变成了如下:

    strs.sort((s1,s2) -> s1.compareTo(s2));
    

    或者

    strs.sort(Comparator.comparing(String::toString));
    

    以前需要5行的代码现在只需要1行,是不是简洁了许多?!

    1. 我们经常会对集合进行遍历,以前的写法是
    List<String> strs = Arrays.asList("1","4","2","3");
    for (String s : strs){
        System.out.println(s);
    }
    

    而使用Lambda表达式,则代码变成了如下

    strs.forEach(s -> System.out.println(s));
    

    或者

    strs.forEach(System.out::println);
    

    Java中的内置函数型接口

    从上面的两个例子可以看出Lambda表达式一般是使用在以匿名类作为参数的方法中,通过传入Lambda表达式对匿名类进行替换。需要注意的是,被替换的匿名类或接口只能有一个方法,这样的接口可以将之称之为函数式接口。同时可以在该接口上添加注解@FunctionalInterface申明该接口为函数式接口。

    在Java8中内置了大量的函数式接口供用户使用,下面为大家介绍几个常用的内置接口。

    1. Function<T, R>:函数型接口,接收类型为T的参数,并对其操作,然后返回类型为R的结果。其中包含有apply(T t)方法。

    举例:对一个字符串进行截取并返回结果

    // 申明方法
    public String subStr(String str, Function<String, String> function){
        return function.apply(str);
    }
    // 调用
    subStr("我Code,我快乐", str -> str.substring(0, 2));
    
    1. Consumer<T>:消费型接口,接收类型为T的参数,对其进行操作。无返回值。其中包含有accept(T t)方法。

    举例:打印一句话

    // 申明方法
    public void print(String s, Consumer<String> consumer){
        consumer.accept(s);
    }
    // 调用
    print("我Code,我快乐", System.out::println);
    
    1. Supplier<T>:供应型接口,返回类型为T的结果。其中包含有T get()的方法。

    举例:获取一个UUID字符串

    // 申明方法
    static String get(Supplier<String> supplier){
        return supplier.get();
    }
    // 调用
    String uuid = get(() -> UUID.randomUUID().toString());
    
    1. Predicate<T>:断言型函数,接收类型为T的参数,对其进行断言,返回类型为boolean的结果。其中包含有boolean test(T t)的方法。

    举例:判断字符串是否以制定字符开头

    // 申明方法
    static boolean startWith(String str, Predicate<String> predicate){
        return predicate.test(str);
    }
    // 调用
    boolean result = startWith("I Like Code!", s -> s.startsWith("I"));
    

    Java中内置的常用函数型接口为上述几种,相关接口源码皆可在包java.util.function下进行查看,当然该包下还包含了其他众多函数型接口,有兴趣的可自行查看。

    上述就是本篇文章的所有内容,边学习,边总结,最后再输出,这样才能更加有效的加深自己的理解和印象。希望自己在以后的学习中能够坚持。

    相关文章

      网友评论

        本文标题:Java中使用Lambda表达式

        本文链接:https://www.haomeiwen.com/subject/iwmcgftx.html