Java 8 教程
此 Java 8 教程列出了重要的 Java 8 特性,并提供了此发行版中引入的示例。 所有特性均具有指向详细教程的链接,例如 lambda 表达式,Java 流,函数式接口和日期时间 API 更改。
Java SE 8 是于 2014 年初发布的。 在 Java 8 中,最受关注的特性是 lambda 表达式。 它还具有许多其他重要特性,例如默认方法,流 API 和新的日期/时间 API。 让我们通过示例了解 Java 8 中的这些新特性。
Table of Contents
1\. Lambda Expression
2\. Functional Interface
3\. Default Methods
4\. Streams
5\. Date/Time API Changes
1. Lambda 表达式
Lambda 表达式对于使用 Scala 等其他流行编程语言的我们很多人并不陌生。 在 Java 编程语言中,Lambda 表达式(或函数)只是匿名函数,即不带名称且不受标识符限制的函数。 它们准确地写在需要的地方,通常以作为其他函数的参数。
Lambda 表达式的基本语法为:
either
(parameters) -> expression
or
(parameters) -> { statements; }
or
() -> expression
典型的 lambda 表达式示例如下所示:
(x, y) -> x + y //This function takes two parameters and return their sum.
请注意,根据x
和y
的类型,方法可能会在多个地方使用。 参数可以匹配int
或Integer
或简单地也可以匹配String
。 根据上下文,它将添加两个整数或连接两个字符串。
编写 Lambda 表达式的规则
- Lambda 表达式可以具有零个,一个或多个参数。
- 参数的类型可以显式声明,也可以从上下文中推断出来。
- 多个参数用强制括号括起来,并用逗号分隔。 空括号用于表示空参数集。
- 当有单个参数时,如果推断出其类型,则不强制使用括号。 例如
a -> a * a
。 - Lambda 表达式的主体可以包含零个,一个或多个语句。
- 如果 lambda 表达式的主体具有单个语句,则不必使用大括号,并且匿名函数的返回类型与主体表达式的返回类型相同。 如果正文中的语句多于一个,则这些语句必须用大括号括起来。
阅读更多: Java 8 Lambda 表达式教程
2. 函数式接口
函数式接口也称为单一抽象方法接口(SAM 接口)。 顾名思义,它们允许其中恰好是一种抽象方法。 Java 8 引入了一个注解,即@FunctionalInterface
,当您注解的接口违反函数式接口的约定时,该注解可用于编译器级错误。
典型的函数式接口示例:
@FunctionalInterface
public interface MyFirstFunctionalInterface {
public void firstWork();
}
请注意,即使省略@FunctionalInterface
注释,函数式接口也有效。 它仅用于通知编译器在接口内部强制执行单个抽象方法。
另外,由于默认方法不是抽象的,因此可以随意向函数式接口添加任意数量的默认方法。
要记住的另一个重要点是,如果接口声明了一个覆盖java.lang.Object
的公共方法之一的抽象方法,那么该接口的任何实现都将具有java.lang.Object
的实现,因此这也不会计入接口的抽象方法数量。 例如,下面是完全有效的函数式接口。
@FunctionalInterface
public interface MyFirstFunctionalInterface
{
public void firstWork();
@Override
public String toString(); //Overridden from Object class
@Override
public boolean equals(Object obj); //Overridden from Object class
}
阅读更多: Java 8 函数式接口教程
3. 默认方法
Java 8 允许您在接口中添加非抽象方法。 这些方法必须声明为默认方法。 Java 8 中引入了默认方法以启用 lambda 表达式的特性。
默认方法使您可以向库的接口添加新特性,并确保与为这些接口的较早版本编写的代码二进制兼容。
让我们看一个例子:
public interface Moveable {
default void move(){
System.out.println("I am moving");
}
}
Moveable
接口定义了一种方法move()
,并提供了默认实现。 如果有任何类实现了此接口,则无需实现其自己的move()
方法版本。 它可以直接调用instance.move()
。 例如:
public class Animal implements Moveable{
public static void main(String[] args){
Animal tiger = new Animal();
tiger.move();
}
}
Output: I am moving
如果类愿意自定义move()
方法的行为,则它可以提供自己的自定义实现并覆盖该方法。
重做更多: Java 8 默认方法教程
4. Java 8 流
引入的另一项重大更改是 Java 8 流 API ,它提供了一种以各种方式处理一组数据的机制,这些方式可以包括过滤,转换或任何其他可能对应用程序有用的方式。
Java 8 中的 流 API 支持不同类型的迭代,您可以在其中简单地定义要处理的项目集,对每个项目执行的操作,以及存储这些操作的输出。
流 API 的示例。 在此示例中,items
是String
值的集合,您想删除以某些前缀文本开头的条目。
List<String> items;
String prefix;
List<String> filteredList = items.stream().filter(e -> (!e.startsWith(prefix))).collect(Collectors.toList());
这里items.stream()
表示我们希望使用 流 API 处理items
集合中的数据。
阅读更多: Java 8 内部和外部迭代
5. Java 8 日期/时间 API 更改
新的日期和时间 API /类(JSR-310),也称为 ThreeTen ,它们仅改变了您在 Java 应用程序中处理日期的方式。
日期
Date
类甚至已过时。 打算替换Date
类的新类是LocalDate
,LocalTime
和LocalDateTime
。
LocalDate
类表示日期。 没有时间或时区的表示。LocalTime
类表示时间。 没有日期或时区的表示。LocalDateTime
类表示日期时间。 没有时区的表示。
如果您想将日期特性与区域信息一起使用,则 Lambda 会为您提供额外的 3 类,类似于上面的一种,即OffsetDate
,OffsetTime
和OffsetDateTime
。 时区偏移可以以“+05:30
”或“Europe/Paris
”格式表示。 这是通过使用另一个类即ZoneId
完成的。
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.of(12, 20);
LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
时间戳和持续时间
为了随时表示特定的时间戳,需要使用的类是Instant
。 Instant
类表示精确到纳秒的时间瞬间。 即时操作包括与另一个Instant
进行比较,以及增加或减少持续时间。
Instant instant = Instant.now();
Instant instant1 = instant.plus(Duration.ofMillis(5000));
Instant instant2 = instant.minus(Duration.ofMillis(5000));
Instant instant3 = instant.minusSeconds(10);
Duration
类是用 Java 语言首次带来的全新概念。 它表示两个时间戳之间的差异。
Duration duration = Duration.ofMillis(5000);
duration = Duration.ofSeconds(60);
duration = Duration.ofMinutes(10);
Duration
处理较小的时间单位,例如毫秒,秒,分钟和小时。 它们更适合与应用程序代码进行交互。 要与人互动,您需要使持续时间更长,该类与Period
类一起提供。
Period period = Period.ofDays(6);
period = Period.ofMonths(6);
period = Period.between(LocalDate.now(), LocalDate.now().plusDays(60));
阅读更多: Java 8 日期和时间 API 更改
在注释部分中,将您对此 Java 8 教程的问题留给我。
学习愉快!