# 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)
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))
// 这里也可以传入其他方法,只要方法签名一样就可以。
2
3
4
5
6
7
8
9
10
构造器引用:它的语法是
Class::new,或者更一般的Class< T >::newfinal Car car = Car.create( Car::new ); final List< Car > cars = Arrays.asList( car );1
2静态方法引用:它的语法是
Class::static_methodcars.forEach( Car::collide );1特定类的任意对象的方法引用:它的语法是
Class::methodcars.forEach( Car::repair );1特定对象的方法引用:它的语法是
instance::methodfinal Car police = Car.create( Car::new ); cars.forEach( police::follow );1
2
# 函数式接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
函数式接口可以被隐式转换为 Lambda 表达式。
JDK 1.8 之前已有的函数式接口:
java.lang.Runnablejava.util.concurrent.Callablejava.util.Comparatorjava.io.FileFilterjava.security.PrivilegedActionjava.nio.file.PathMatcherjava.lang.reflect.InvocationHandlerjava.beans.PropertyChangeListenerjava.awt.event.ActionListenerjavax.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);
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
# Base64
在 Java 8 中,Base64 编码已经成为了 Java 类库的标准,Java 8 内置了 Base64 的编/解码器。
Base64 提供了
# TODO
# 讨论区
由于评论过多会影响页面最下方的导航,故将评论区做默认折叠处理。
点击查看评论区内容,渴望您的宝贵建议~
← Java 多线程