首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java8 Lambda表达式入门

Java8 Lambda表达式入门

作者头像
卡尔曼和玻尔兹曼谁曼
发布2019-01-22 15:26:37
4790
发布2019-01-22 15:26:37
举报

Lambda表达式的实质就是一个匿名函数。C#3.0引入了Lambda表达式,Java8也不甘示弱。Java8发布很久了,今天安装了JDK体验了Java8中的Lambda表达式。

首先看一个不适用Lambda表达式的例子。 比如我们要对一组字符串进行排序。

public class Hello {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Tan", "Zhen", "Yu");
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return a.compareTo(b);
            }
        });
        for (String name : names) {
            System.out.println(name);
        }
    }
}

运行结果:

Tan
Yu
Zhen

同样的例子看一下使用Lambda表达式的代码:

public class Hello {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Tan", "Zhen", "Yu");
        Collections.sort(names, (String a, String b) -> a.compareTo(b));
        Stream<String> stream = names.stream();
        stream.forEach(System.out::println);
    }
}

是不是简洁很多。

下面详细介绍下Java8中的Lambda表达式。 (String a, String b) -> a.compareTo(b)就是一个Lambda表达式。前面括号中是函数的参数列表,->符号后面的是函数体。所以Lambda表示的写法是前面使用小括号列出函数参数,然后是用->符号指向函数体,函数体一般使用花括号{}括起来。 上面函数体a.compareTo(b)其实是一种简写。完整的写法应该是

(String a, String b) -> {
    returen a.compareTo(b);
}

因为函数体只有一句,一般可以省略大括号和return关键字。

Java中每一个Lambda表达式都对应一个类型,通常是接口类型,使用@FunctionalInterface进行注解。这种“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的Lambda表达式都会被匹配到这个抽象方法。即就是说每一个Lambda表达式对应函数式接口中的那个抽象方法。 此外,Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,。所以函数式接口中只能有一个抽象方法,其它的只能是扩展方法。下面是Java8中的Comparator接口,compare是抽象方法,此外还有一些扩展方法。

@FunctionalInterface
public interface Comparator { 
    int compare(T o1, T o2);
    ......
}

在上面的示例代码中stream.forEach(System.out::println)一句的作用是使用Stream API输出每个字符串,下面进行详细解释。 Java 8引入了全新的Stream API。这里的Stream和I/O流不同,它更像具有Iterable的集合类,但行为和集合类又有所不同。Stream API引入的目的在于弥补Java函数式编程的缺陷。对于很多支持函数式编程的语言,map()、reduce()基本上都内置到语言的标准库中了(比如像Python和JavaScript这些语言)。 创建一个Stream有很多方法,最简单的方法是把一个Collection变成Stream,像上面的Stream<String> stream = names.stream()。 集合类新增的stream()方法用于把一个集合变成Stream,然后,通过filter()、map()等实现Stream的变换。Stream还有一个forEach()来完成每个元素的迭代。

这是forEach方法的签名void forEach(Consumer<? super T> action)。Consumer<? super T>也是一个函数式接口,所以我们应该传入一个函数。 Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用,像上面的System.out::println是对println函数的引用。如果引用构造函数可以使用对象::new的形式。

个人感觉Java8中的函数式接口的作用和C#中的代理类型(delegate)比较像,或者说作用比较类似。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015年04月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档