Lambda被很多使用高级语言如scala的人所熟知。在程序中,一个Lambda表达式(或函数)仅仅是一个匿名函数,即一个没有名字没有边界标识符的函数。直接卸载需要的地方,通常作为其他函数的参数。
Lambda表达式的基础语法:
either
(parameters) -> expression
or
(parameters) -> {statements;}
or
() -> expression
一个典型的Lambda表达式的例子如下:
(x, y) -> x + y // 这个函数有两个参数,并且返回了相加值
功能接口也被称为单个抽象方法的接口(Single Abstract Method interfaces (SAM Interfaces))。就像名字说描述的,它们只允许一个抽象方法在接口中。Java 8 引入了一个注解@FunctionalInterface,能够在你的注解的接口违反了功能接口的约定时报编译器错误。
一个典型的功能接口例子:
@FunctionalInterface
public interface MyFirstFunctionalInterface {
public void firstWork();
}
请注意一个功能接口即使在省略了@FunctionalInterface注解的情况下依然有效,此注解仅是通知编译器强制该接口仅能有一个抽象方法。
同样,默认方法如果不是抽象的,你能自由的向你的功能接口中添加你想要的默认方法。
另一个需要记住的重点是如果一个接口声明的抽象方法重写了java.lang.Object的public方法。也不计入接口的抽象方法计数中,因为任何接口的实现也会实现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 允许你在接口中添加非抽象方法。这些方法必须声明默认方法。默认方法是引入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 Stream API。它提供了一个能以各种方式(过滤、转换、或者其他应用程序可能会使用的方式)处理一组数据的机制。
Java 8 StreamAPI支持不同类型的迭代。只需要你简单的定义一组元素去处理,每一个元素要执行的操作,以及这些操作的输出存储到哪里。
一个streamAPI的例子。在这个例子中元素是字符串,并且你想要移除某些前缀的文本。
List<String> items;
String prefix;
List<String> filteredList = items.stream().filter(e -> (!e.startsWith(prefix))).collect(Collectors.toList());
新的日期和时间APIS/classes(JSR-310),也被称为ThreeTen,一种简单的在java应用中处理日期的方式。
Date类已经被废弃了。新的准备替代日期类的类是LocalDate,LocalTime,LocalDateTime
1. LocalDate代表日期,不代表时间或时区;
2. LocalTime代表时间,不代表日期或时区
3. 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 = 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));
翻译来源:https://howtodoinjava.com/java-8-tutorial/