Java 9 好像也快出了,不过我连Java 8的新特性都还没认真研究过,所以这几篇文章就是来介绍Java 8的新特性的。首先,第一个重要的特性就是传说中的lambda表达式了,虽然初学可能觉得这东西很难理解,但是一旦学会了,你就会发现离不开它了。

在现代编程语言中,lambda表达式这个语言特性已经成为了标配。当然不同语言中的lambda表达式概念和实现形式可能会稍有差别。不过不管在哪种语言中,我们都可以把lambda表达式简单的理解为匿名函数。在Java中,lambda表达式和只有一个方法的接口是差不多的,所以这样的接口又叫做SAM接口(Single Abstract Method interfaces)

初识lambda表达式

说了半天,下面先来看看实际例子吧。我们在编写多线程代码的时候,常常需要编写实现Runnable的类。有时候为了省事,我们会写成匿名内部类的形式。

Runnable task1 = new Runnable() {@Overridepublic void run() {System.out.println("任务一");}
};

匿名内部类不好理解,而且写起来也非常丑陋。由于Runnable接口内只有一个方法,所以它是一个SAM接口,我们可以用lambda表达式改写它。那么改写之后是什么样子的呢?不要惊讶,只需要一行代码。

Runnable task2 = () -> System.out.println("任务二");

因此,我们可以看到lambda表达式的简洁之处。下面就来详细介绍一下lambda表达式的形式。

lambda表达式形式

lambda表达式可以用在需要SAM接口对象的地方,由于编译器这时候知道所需要的接口和对应方法的签名。所以lambda表达式的类型声明可以省略,具体类型由编译器自行推断。lambda表达式的基本形式如下。

(参数列表) -> {方法体}

为了方便说明,我这里定义了一组接口,用于之后的lambda表达式实现。

@FunctionalInterface
interface Interface1 {void f();
}@FunctionalInterface
interface Interface2 {void f(int a);
}@FunctionalInterface
interface Interface3 {void f(int a, int b);
}@FunctionalInterface
interface Interface4 {int f(int a, int b);
}

无参lambda

先来看看无参数的lambda表达式。特别地,如果方法体只有一行代码,可以省略方法体的大括号。

Interface1 interface1 = new Interface1() {@Overridepublic void f() {System.out.println("f");}
};
Interface1 lambda1 = () -> {System.out.println("f");
};
//如果方法体只有一行代码,可以省略大括号
Interface1 lambda1a = () -> System.out.println("f");

多个参数的lambda

我们可以看到由于编译器可以进行类型推断,所以lambda表达式的参数列表不需要参数类型声明,而且由于我只有一行代码,所以大括号也省略了。

//多个参数lambda
Interface3 interface3 = new Interface3() {@Overridepublic void f(int a, int b) {System.out.println(a + b);}
};
Interface3 lambda3 = (a, b) -> System.out.println(a + b);

带返回值的lambda

带返回值的lambda表达式其实和普通的一样,只不过需要在方法体的最后使用return语句。值得注意的是最后一个例子,如果方法体本身足够简单,可以直接将返回值表达式写在lambda表达式的右边,编译器也会正确对待这种情况。

//带有返回值的lambda
Interface4 interface4 = new Interface4() {@Overridepublic int f(int a, int b) {return a + b;}
};
Interface4 lambda4 = (a, b) -> {return a + b;
};
Interface4 lambda4a = (a, b) -> a + b;

单个参数的lambda

如果lambda表达式只有一个参数,那么参数列表的小括号也可以省略,例如下面的第二个例子。下面第三个例子演示了另一个新语法方法引用,如果lambda表达式的形式是单个参数a -> 某个只有一个参数的方法(a),那么就可以简写成方法引用的形式类::方法。方法引用是一个新语法,如果见到了不要奇怪,这也是正确的Java代码。

//一个参数的lambda
Interface2 interface2 = new Interface2() {@Overridepublic void f(int a) {System.out.println(a);}
};
Interface2 lambda2 = (a) -> System.out.println(a);
Interface2 lambda2a = a -> System.out.println(a);
Interface2 methodReference = System.out::println;

函数接口

@FunctionalInterface注解
如果查看JDK源码的一些接口,会发现它们上面添加了@FunctionalInterface注解。例如上面提到的Runnable接口。

@FunctionalInterface
public interface Runnable {public abstract void run();
}

这个注解用于标注函数接口,也就是上面提到的SAM接口。如果一个接口中包含了不止一个方法,那么函数接口注解就会触发编译错误。这个功能类似于@Override注解。当然并不是说要使用lambda表达式必须标记这个注解,只要接口中只有一个方法,那么就可以使用lambda表达式。

其实函数接口可以包括不止一个方法,除了一个普通的抽象方法之外,函数接口还可以包含一个在java.lang.Object类中声明的方法。Java 8新增了默认方法特性,如果接口的实现类没有实现java.lang.Object类中的这些基本方法,那么就会调用java.lang.Object类中的实现作为默认实现。

@FunctionalInterface
interface Interface5 {void f();String toString();
}

预定义的函数接口

在java.util.function包下定义了大量预定义的函数接口,它们包含了各种各样的形式,基本涵盖了编程的各个方面。同学们最好对这些函数接口的形式稍作了解,以后碰到的时候就不会一头雾水了。

lambda表达式应用

编写线程

前面提到了,可以使用lambda表达式简化线程代码的编写,不再需要冗长的匿名内部类。

//编写线程
Runnable task = () -> System.out.println("简单的任务");
Executor executor = Executors.newCachedThreadPool();
executor.execute(task);

编写比较器

比方说我们有一个学生类,有姓名和年龄两个字段。如果需要按照某种规则来进行排序,可以使用比较器Comparator接口来比较,利用lambda表达式同样可以简化这部分代码的编写。

class Student {private String name;private int age;//其余方法已省略
}

可以看到比较规则只需要一条lambda表达式即可传入,非常方便。后面两个例子是Comparator接口新增的工具方法,可以帮助我们简化比较代码的编写,这里使用了方法引用来简化代码。comparing等方法的返回值仍然是Comparator,所以可以链式调用进行多级比较。

List<Student> students = new ArrayList<>();
students.add(new Student("yitian", 25));
students.add(new Student("anna", 26));
students.add(new Student("wang5", 24));students.sort((a, b) -> a.getAge() - b.getAge());
System.out.println(students);students.sort(Comparator.comparing(Student::getName));
System.out.println(students);students.sort(Comparator.comparing(Student::getName).thenComparing(Student::getAge));
System.out.println(students);

作者:乐百川
链接:https://www.jianshu.com/p/583dad6dcd8b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Java 8 新特性(一)lambda表达式相关推荐

  1. 深圳Java培训学习:Java8.0新特性之Lambda表达式--【千锋】

    深圳Java培训学习:Java8.0新特性之Lambda表达式–[千锋] 前言 Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.本篇文章,主要给大家介绍的是lambda表 ...

  2. java x=8_Java8新特性之lambda表达式

    简介 Java8带来的新特性之一Lambda表达式,又称之为函数式编程,核心思想是将面向对象中的传递对象变为传递行为 语法 expression = (variable) -> anction ...

  3. java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合

    java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...

  4. JDK8新特性之Lambda表达式

    转载自 JDK8新特性之Lambda表达式 什么是Lambda表达式 Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁.当开发者在编写Lambda表达式时,也会随之被编译成 ...

  5. 【java8新特性】——lambda表达式与函数式接口详解(一)

    一.简介 java8于2014年发布,相比于java7,java8新增了非常多的特性,如lambda表达式.函数式接口.方法引用.默认方法.新工具(编译工具).Stream API.Date Time ...

  6. java8新特性之lambda表达式--超级详细版本

    java8新特性之lambda表达式 1.什么是lambda表达式?为什么用它? 2. 为什么Java需要lambda表达式? 3. lambda表达式的语法 4.函数式接口 4.1 什么是函数式接口 ...

  7. Java8 新特性:Lambda 表达式、方法和构造器引用、Stream API、新时间与日期API、注解

    Java8新特性:Lambda 表达式.方法和构造器引用.Stream API.新时间与日期API.注解 1.Java8新特性 1.1.主要的新特性: 1.2.编程风格 2.Lambda 表达式 2. ...

  8. Java 8 新特性之Lambda

    Java 8 新特性之Lambda.Stream.Optional Java 8 新特性之Lambda.Stream.Optional 速度更快 代码更少(增加了新的语法Lambda表达式) 强大的S ...

  9. java:java8新特性(Lambda 表达式、方法引用、构造器引用、数组引用、Stream API)

    速度更快 对 HashMap .ConcurrentHashMap低层的数据结构(数组+链表+二叉树) 低层的内存结构(将永久区更新为元空间,元空间使用的是物理内存) 代码更少(增加了新的语法 Lam ...

  10. lambda 对象去重_最火的java8新特性:Lambda 表达式

    主要内容 1. Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 其他新特性 Java 8新特性简介 速度更快 代码更少(增加了新的语法 Lambd ...

最新文章

  1. GridControl 选择列、复选框全选(上)
  2. PyTorch框架学习二——基本数据结构(张量)
  3. 20个响应式网页设计中的“神话”误区
  4. django目录介绍
  5. 加减法计算器-java
  6. MPLS ××× 基本实验测试
  7. 你的IE一路顺风吗?
  8. awr报告 解读_Oracle Awr报告_awr报告解读_基础简要信息
  9. 2 4G高频PCB天线设计
  10. Sopcast for linux更新至3.01!
  11. MongoDB学习笔记
  12. 为什么算法这么难???
  13. 仪表板展示|DataEase可视化数据分析工具中的仪表板跳转和联动设置
  14. JavaWeb_基础知识
  15. TypeScript 2
  16. csp2021-09-4 收集卡牌
  17. 6-5 Approximating Eigenvalues (40分)
  18. 博弈论--从 必胜点与必败点 到 SG 函数
  19. 华为计算机apk,华为手机助手安卓版apk
  20. 太准了这十个心理暗示

热门文章

  1. MSSQL 2000更改表和存储过程的所有者
  2. 两个HC-05蓝牙模块互相绑定构成无线串口模块
  3. java-Servlet编码/异常处理
  4. 客户端与服务站《Socket》
  5. STL学习笔记--歌唱比赛(综合题)
  6. ios 解压下载数据包(zip)
  7. 是谁让网管员的薪水如此低廉?
  8. Json-getJSON
  9. 33.Linux/Unix 系统编程手册(上) -- 线程:更多细节
  10. 11. 文件上传漏洞