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