Java 8于2014年初发布。本文列出了重要的 Java 8 特性,并提供了 lambda 表达式、Java 流、函数式接口、接口默认方法和日期时间 API 更改等功能的代码示例。
1. Lambda表达式
使用Scala的同学已经很熟悉Lambda表达式了。在Java编程语言中,Lambda表达式只是一个匿名函数,就是没有名称并且没有任何修饰符的函数。
1.1 lambda语法
lambda 表达式的基本语法:
//如果 lambda 表达式的正文具有单个语句,则可以不要大括号
//并且匿名函数的返回类型与正文表达式的返回类型相同。
(parameters) -> expression
// 当正文中有多个语句时,这些语句必须括在大括号中。
(parameters) -> { statements;
}
//空括号用于表示一组空参数
() -> expression
例如:
//这个lambda表达式接收两个参数并返回它们的和
(x, y) -> x + y
上面这个例子可以作为两个整型数字相加,也可以用于连接两个字符串,Java会根据上下文自动进行类型匹配。
1.2 lambda编写规则
- lambda 表达式可以有零个、一个或多个参数。
- 参数的类型可以显式声明,也可以从上下文中推断出来。
- 多个参数括在小括号中,并用逗号分隔。空括号用于表示一组空参数。
- 当只有单个参数时,如果推断出其类型,则不必使用括号。
- lambda 表达式的主体可以包含零个、一个或多个语句。
- 如果 lambda 表达式的正文具有单个语句,则可以不要大括号,并且匿名函数的返回类型与正文表达式的返回类型相同。当正文中有多个语句时,这些语句必须括在大括号中。
Java 8引入了新的注解
@FunctionalInterface
,我们可以使用它来给出编译时错误,检验功能接口是否违反了规约。2.1 示例
//可选注解,也可以不写注解
@FunctionalInterface
public interface MyFirstFunctionalInterface {
public void onlyOneMethod();
}
即使省略注释
@FunctionalInterface
,函数式接口也是有效的。它仅用于通知编译器在接口内强制实施单个抽象方法。另外,因为默认方法不是抽象方法,其有一个默认实现,所以是符合函数式接口的定义的。
要记住的另一个关键点是,如果函数接口覆盖了基类(
java.lang.Object
)的公共方法之一,则该方法也不计入接口的抽象方法总数,因为该接口的任何实现都将具有来自(java.lang.Object
)或其他地方的实现。下面给出的是一个完全有效的功能接口:
@FunctionalInterface
public interface MyFirstFunctionalInterface
{
public void onlyOneMethod();
@Override
public String toString();
@Override
public boolean equals(Object obj);
}
3. 默认方法 Java 8允许我们在接口中添加非抽象方法。这些方法必须声明为
default
方法。Java 8 中引入默认方法,以便更好的使用 lambda 表达式的功能。默认方法使我们能够为库的接口引入新功能,并确保与为这些接口的旧版本编写的代码的二进制兼容性。
让我们通过一个例子来理解:
public interface Moveable {
default void move(){
System.out.println("I am moving");
}
}
Moveable接口定义了一个move()方法,并提供了一个默认的实现。如果任何类实现此接口,则它不需要实现自己的move()方法,它可以直接调用实例后的move()方法。
例如:
public class Animal implements Moveable{
public static void main(String[] args){
Animal tiger = new Animal();
tiger.move();
}
}
//打印:I am moving
如果类愿意自定义move()方法的行为,那么它可以提供自己的自定义实现并重写该move()方法。
4. Java流 Java8另一个重大变化是引入了流,它提供了一种机制,用于以各种方式处理数据,包括过滤、转换或可能对应用程序有用的任何其他方式。
Java 8 中的 流(Streams) API 支持不同类型的迭代,在该迭代中,我们定义了要处理的项集、要对每个项执行的操作以及要存储这些操作的输出位置。
4.1 示例
在下面这个示例中,我们想要删除前缀有
str
的数据:package cn.dayangshuo;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author DAYANG
*/
public class StreamTest {
public static void main(String[] args) {
List items = Arrays.asList("str123", "dayang", "大阳");
String prefix = "str";
List filteredList = items.stream()
.filter(e -> (!e.startsWith(prefix)))
.collect(Collectors.toList());
filteredList.forEach(System.out::println);
}
}
//打印内容:
//dayang
//大阳
5. Java8时间/日期API更改 新的日期和时间 API/类 (JSR-310),也称为 ThreeTen,只是改变了我们在 java 应用程序中处理日期的方式。
5.1 日期类/时区类
Data类已经过时了。用于替换 Date 类的新类是 LocalDate、LocalTime和LocalDateTime
- LocalDate:表示一个日期,没有时间或时区的信息
- LocalTime:表示一个时间,没有日期或时区的信息
- LocalDateTime表示日期和时间,没有时区信息
示例:
//此刻日期
LocalDate localDate = LocalDate.now();
//时间
LocalTime localTime = LocalTime.of(12, 20);
//此刻日期时间
LocalDateTime localDateTime = LocalDateTime.now();
//2017-03-13T11:28:29.247+08:00:东八区时间
OffsetDateTime offsetDateTime = OffsetDateTime.now();
//2017-03-13T04:28:29.248+01:00[Europe/Paris]:欧洲巴黎时间
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
5.2 时间戳和持续时间类
为了表示任何时刻的特定时间戳,需要使用的类是
Instant
。该类表示精确度为纳秒的瞬间。示例:对
Instant
与另一个Instant
进行比较的操作,并添加或减去一些时间//2017-03-13T03:38:57.134Z
Instant instant = Instant.now();
//2017-03-13T03:38:57.134Z
Instant instant1 = instant.plus(Duration.ofMillis(5000));
//2017-03-13T03:38:47.134Z
Instant instant2 = instant.minus(Duration.ofMillis(5000));
//2017-03-13T03:38:42.134Z
Instant instant3 = instant.minusSeconds(10);
Duration
类(持续时间)是Java8中首次出现的全新概念。它表示两个时间戳之间的时间差。Duration
处理一小段时间单位,如毫秒、秒、分钟和小时。它们更适合与应用程序代码交互。Duration duration = Duration.ofMillis(5000);
duration = Duration.ofSeconds(60);
duration = Duration.ofMinutes(10);
【Java8新特性及代码示例】处理更大的时间间隔,可以使用
Period
类Period period = Period.ofDays(6);
period = Period.ofMonths(6);
period = Period.between(LocalDate.now(), LocalDate.now().plusDays(60));
推荐阅读
- 代付|微信公众号如何实现支付功能()
- Java毕业设计项目实战篇|Java项目:企业人事管理系统(java+SSM+jsp+mysql+maven)
- java|使用Spring连接mysql数据库
- Leetcode|leetcode-蜡烛之间的盘子(经典空换时)
- java|== 和 equals 的区别你知道吗()
- 面试题|操作系统高频面试题
- #|【JavaWeb】Cookie和Session解析
- #|【JavaWeb】文件的上传和下载
- 图解Redis|什么是缓存雪崩、击穿、穿透()