动力节点旗下在线教育品牌  |  咨询热线:400-8080-105 学Java全栈,上蛙课网
首页 > 文章

Java语法的双刃剑—Lambda表达式

06-29 17:40 246浏览
举报 T字号
  • 大字
  • 中字
  • 小字

Lambda表达式作为Java SE 8中一个重要的新特性,它允许将函数作为参数进行传递(函数式编程),能够极大的简洁代码,在Java SE8中扮演着举足轻重的角色,发挥着独一无二的作用。本文详细地向大家来介绍java 8家族的新成员—Lambda表达式。

lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。lambda表达式还增强了集合库。Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及 java.util.stream 包。流(stream)就如同迭代器(iterator),但附加了许多额外的功能。总的来说,lambda表达式和stream是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。

Lambda表达式使你可以封装行为的单个单元,并将其传递给其他代码。如果要在集合的每个元素上执行特定操作,流程完成或流程遇到错误时,可以使用lambda表达式。以下功能支持Lambda表达式:

1.方法引用是紧凑的,易于阅读的lambda表达式,用于具有名称的方法。

2.默认方法使你可以向库的接口添加新功能,并确保与为这些接口的较早版本编写的代码二进制兼容。它们是接口方法,default在方法签名的开头具有实现和关键字。另外,你可以在接口中定义静态方法。

3.利用Java SE 8中的Lambda表达式和流的新的和增强的API描述了利用Lambda表达式和流的新的和增强的类。

以最常见到的使用Runnable创建线程为例。

使用匿名内部类创建:

Thread thread = new Thread(new Runnable() {

            @Override

            public void run() {

                System.out.println("do something here");

            }

        },"thread");

使用lambda表达式的形式创建:

Thread thread = new Thread(() -> System.out.println("do something here"), "thread");

很容易看出来代码的锐减程度很大,看起来也很简洁,极大地提高了代码的效率。

Lambda表达式的语法

基本语法:

参数 -> 表达式

(parameters) -> expression

(parameters) ->{ statements; }

下面是Java lambda表达式的简单例子:

// 1. 不需要参数,返回值为 5

() -> 5

// 2. 接收一个参数(数字类型),返回其2倍的值

x -> 2 * x

// 3. 接受2个参数(数字),并返回他们的差值

(x, y) -> x – y

// 4. 接收2个int型整数,返回他们的和

(int x, int y) -> x + y

// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)

(String s) -> System.out.print(s)

现在,我们已经知道什么是lambda表达式,让我们先从一些基本的例子开始。我们将从中看到lambda表达式如何影响我们编码的方式。 假设有一个玩家List ,程序员可以使用 for 语句 ("for 循环")来遍历,在Java SE 8中可以转换为另一种形式:

String[] atp = {"Rafael Nadal", "Novak Djokovic",

       "Stanislas Wawrinka",

       "David Ferrer","Roger Federer",

       "Andy Murray","Tomas Berdych",

       "Juan Martin Del Potro"};

List players =  Arrays.asList(atp);

// 以前的循环方式

for (String player : players) {

     System.out.print(player + "; ");

}

// 使用 lambda 表达式以及函数操作(functional operation)

players.forEach((player) -> System.out.print(player + "; "));

// 在 Java 8 中使用双冒号操作符(double colon operator)

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

正如您看到的,lambda表达式可以将我们的代码缩减到一行。 另一个例子是在图形用户界面程序中,匿名类可以使用lambda表达式来代替。 同样,在实现Runnable接口时也可以这样使用:

// 使用匿名内部类

btn.setOnAction(new EventHandler() {

          @Override

          public void handle(ActionEvent event) {

              System.out.println("Hello World!");

          }

    });

 

// 或者使用 lambda expression

btn.setOnAction(event -> System.out.println("Hello World!"));

下面是使用lambdas 来实现 Runnable接口 的示例:

// 1.1使用匿名内部类

new Thread(new Runnable() {

    @Override

    public void run() {

        System.out.println("Hello world !");

    }

}).start();

// 1.2使用 lambda expression

new Thread(() -> System.out.println("Hello world !")).start();

// 2.1使用匿名内部类

Runnable race1 = new Runnable() {

    @Override

    public void run() {

        System.out.println("Hello world !");

    }

};

// 2.2使用 lambda expression

Runnable race2 = () -> System.out.println("Hello world !");

// 直接调用 run 方法(没开新线程哦!)

race1.run();

race2.run();

Runnable 的 lambda表达式,使用块格式,将五行代码转换成单行语句。接下来,在下一节中我们将使用lambdas对集合进行排序。

使用Lambdas排序集合

Java中,Comparator 类被用来排序集合。在下面的例子中,我们将根据球员的 name, surname, name 长度 以及最后一个字母。和前面的示例一样,先使用匿名内部类来排序,然后再使用lambda表达式精简我们的代码。

在第一个例子中,我们将根据name来排序list。使用旧的方式,代码如下所示:

String[] players = {"Rafael Nadal", "Novak Djokovic",

    "Stanislas Wawrinka", "David Ferrer",

    "Roger Federer", "Andy Murray",

    "Tomas Berdych", "Juan Martin Del Potro",

    "Richard Gasquet", "John Isner"};

// 1.1 使用匿名内部类根据 name 排序 players

Arrays.sort(players, new Comparator() {

    @Override

    public int compare(String s1, String s2) {

        return (s1.compareTo(s2));

    }

});

使用lambdas,可以通过下面的代码实现同样的功能:

// 1.2 使用 lambda expression 排序 players

Comparator sortByName = (String s1, String s2) -> (s1.compareTo(s2));

Arrays.sort(players, sortByName);

// 1.3 也可以采用如下形式:

Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));

从上面的几个例子中我们不难看出Lambda表达式的几个特征:

1.可选的类型声明:编译器可以通过上下文来推到类型。

2.可选的参数括号:如果只有一个参数,可以不定义括号。

3.可选的大括号:如果函数体只有一条语句,可以省略大括号。

4.可选的返回关键字:如果主体只有一个表达式返回值,则编译器会自动返回值。

lambda最重要的一点是延迟执行,毕竟如果要立即执行代码的话,完全没有必要写再lambda表达式中。超过3行的逻辑就不适用Lambda表达式了。虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。但是建议不要乱用lambda,因为这就和某些很高级的黑客写的代码一样,简洁,难懂,难以调试,会给维护人员带来大量的工作量。

所以说lambda表达式在java语法中是一把双刃剑,让你用更少的代码实现同样的功能的同时,也会给代码的维护带来麻烦。合理规范地使用这个java家族的新成员,“千里马常有,而伯乐不常有。”,java中好的语法有很多,我们要想做它们的‘伯乐’,就要打好java语法的基础,不断求知进取,为了成为一名java大师而努力拼搏奋斗!

0人推荐
共同学习,写下你的评论
0条评论
轻言绕指柔
程序员轻言绕指柔

14篇文章贡献84145字

作者相关文章更多>

推荐相关文章更多>

Java数据结构

HelloWorld10-31 08:24

浅谈MySQL中SQL优化的常用方法

军哥08-12 23:29

五分钟读懂UML类图

江湖人称小李白12-10 10:41

MyBatis开发框架的四大核心

IT逐梦者08-17 21:43

一次搞定continue,break和return

HelloWorld11-06 11:19

发评论

举报

0/150

取消