# Java 8 Feature

# 参考文档

# 主要特性

  • Lambda 表达式
    • Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
  • 方法引用
    • 方法引用提供了非常有用的语法,可以直接引用已有 Java 类或对象(实例)的方法或构造器。与 Lambda 联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
  • 函数式接口
  • 接口默认方法
    • 默认方法就是一个在接口里面有了一个实现的方法。
  • Stream API
    • 新添加的 Stream API(java.util.stream)把真正的函数式编程风格引入到 Java 中。
  • Optional 类
    • Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
  • Date Time API
    • 加强对日期与时间的处理。
  • Base64
    • 在 Java 8 中,Base64 编码已经成为 Java 类库的标准。
  • 新工具
    • 新的编译工具,如:
      • Nashorn 引擎 jjs
      • 类依赖分析器 jdeps
  • Nashorn,JavaScript 引擎
    • Java 8 提供了一个新的 Nashorn javascript 引擎,它允许我们在 JVM 上运行特定的 javascript 应用。

# Lambda

Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。

目的:替代匿名类。

格式:(x,y) -> {x+y}

示例:

// 1. 不需要参数,返回值为 5
() -> 5

// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x

// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y

// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y

// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 变量作用域

Lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 Lambda 内部修改定义在域外的局部变量,否则会编译错误。

Lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)。

在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

# 方法引用

方法引用可以使语言的构造更紧凑简洁,减少冗余代码。

格式:使用 ::

在 Lambda 表达式中使用,可以直接传入方法签名一样的方法,即除了方法名以外,方法参数,返回值都一致。

示例:

// 以数组中的字符串为 userName 创建 User
List<String> strings = Arrays.asList("one", "two", "three", "four", "five");
// 不使用方法引用
strings.stream().map(x -> new User(x)).forEach(x -> System.out.println());
// 方法引用写法
strings.stream().map(User::new).forEach(System.out::println);
// 这里是 new User() 构造方法需要一个参数 String userName,
// 那么这里 .map(User::new) 等同于 .map(x -> new User(x))

// 这里也可以传入其他方法,只要方法签名一样就可以。
1
2
3
4
5
6
7
8
9
10
  • 构造器引用:它的语法是 Class::new,或者更一般的 Class< T >::new

    final Car car = Car.create( Car::new );
    final List< Car > cars = Arrays.asList( car );
    
    1
    2
  • 静态方法引用:它的语法是 Class::static_method

    cars.forEach( Car::collide );
    
    1
  • 特定类的任意对象的方法引用:它的语法是 Class::method

    cars.forEach( Car::repair );
    
    1
  • 特定对象的方法引用:它的语法是 instance::method

    final Car police = Car.create( Car::new );
    cars.forEach( police::follow );
    
    1
    2

# 函数式接口

函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

函数式接口可以被隐式转换为 Lambda 表达式。

JDK 1.8 之前已有的函数式接口:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.util.Comparator
  • java.io.FileFilter
  • java.security.PrivilegedAction
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

JDK 1.8 新增的函数接口:java.util.function 包常用接口

  • Supplier<T> - 0 入参 1 返回
  • Consumer<T> - 1 入参 0 返回
  • Function<T,R> - 1 入参 1 返回
  • Predicate<T> - 1 入参 1 boolean 返回
  • BiConsumer<T,U> - 2 入参 0 返回
  • BiFunction<T,U,R> - 2 入参 1 返回
  • 其它类似...

# 接口默认方法

Java 8 允许接口使用 default 关键字实现默认方法。

Java 8 接口可以声明并实现静态方法。

# Stream API

Stream 分为 stream() 串行流parallelStream 并行流

Stream 不调用终止方法,中间操作(map、filter...)不会执行。使用 Stream.collect() 将流收集到数组、列表等集合中去。

示例:

Stream<String> stringStream = Stream.of("h", "e", "l", "l", "o");
List<String> l = stringStream.filter(c -> c.equals("l")).collect(Collectors.toList());
l.forEach(System.out::println);
1
2
3

# 获取 Stream 方式

  • Stream.of()
  • Collection/Arrays.stream()

# 中间方法

  • forEach
  • map
  • flatMap
  • filter
  • sorted
  • limit
  • collect

# Optional 类

Optional 类的引入很好的解决空指针异常。

Optional 类是一个可以为 null 的容器对象。如果值存在则 isPresent() 方法会返回 true,调用 get() 方法会返回该对象。

Optional 是个容器:它可以保存类型 T 的值,或者仅仅保存 null

Optional 提供很多有用的方法,这样我们就不用显式进行空值检测:

  • get()
  • void ifPresent(Consumer<? super T> consumer)
  • <U>Optional<U> map(Function<? super T,? extends U> mapper)
  • static <T> Optional<T> of(T value)
  • static <T> Optional<T> of(T value)
  • T orElse(T other)
  • T orElseGet(Supplier<? extends T> other)
  • <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
  • ...

# Date Time API

新旧 Time lib

# Base64

在 Java 8 中,Base64 编码已经成为了 Java 类库的标准,Java 8 内置了 Base64 的编/解码器。

Base64 提供了

# TODO

# 讨论区

由于评论过多会影响页面最下方的导航,故将评论区做默认折叠处理。

点击查看评论区内容,渴望您的宝贵建议~
Last Updated: 6/10/2022, 3:54:48 PM