java8的新特性
Java8特性指南
Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。
注:API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。 [1] 用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。
java SE 8
- 自java5以来最大的版本变动
- 很大程度增强java类库
- 主要目标
- 更高的开发效率
- 更高代码可靠性
- 项更好利用多核和多处理器系统
- 项 代码不再串行执行
Lambdas表达式
- Lambda表达式(也称为闭包)是整个Java 8发行版中最受期待的在Java语言层面上的改变,Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),或者把代码看成数据:函数式程序员对这一概念非常熟悉。在JVM平台上的很多语言(Groovy,Scala,……)从一开始就有Lambda,但是Java程序员不得不使用毫无新意的匿名类来代替lambda。
- 实例:
下面展示一些内联代码片。
// A code block
Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> {
int result = e1.compareTo( e2 );
return result;
} );
- 函数式接口:只包含一个方法的接口
语法:(parameters) -> expression 或者 (parameters) -> { statements; } - 方法引用
跟 lambda 表达式一样的
语法:ObjectReference::methodName
**以前的做法:
下面展示一些内联代码片。
// A code block
var foo = 'bar';
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(“实现的线程 ");
}
}).start();
Lambda实现方式:
new Thread(() ->System.out.println("lambda实现的线程")).start();
Functional接口
- 函数式接口就是一个具有一个方法的普通接口。像这样的接口,可以被隐式转换为lambda表达式。java.lang.Runnable与java.util.concurrent.Callable是函数式接口最典型的两个例子。在实际使用过程中,函数式接口是容易出错的:如有某个人在接口定义中增加了另一个方法,这时,这个接口就不再是函数式的了,并且编译过程也会失败。为了克服函数式接口的这种脆弱性并且能够明确声明接口作为函数式接口的意图,Java 8增加了一种特殊的注解@FunctionalInterface(Java 8中所有类库的已有接口都添加了@FunctionalInterface注解)。
- 下面展示一些
内联代码片。
// A code block
@FunctionalInterface
public interface FunctionalDefaultMethods {
void method();
default void defaultMethod() {
}
}
// Java 8之前: new Thread(new Runnable() {
@Override public void run() {
System.out.println("Before Java8");
} }).start();
//Java 8方式:
new Thread( () -> System.out.println("In Java8, Lambda ") ).start();
默认方法
- 提供相应机制将新方法添加到现有接口
- 未破环向后兼容性
- 为 Java 提供行为及类型(而不是状态!)的多继承
// A code block
public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public class Clazz implements A {
public static void main(String[] args){
Clazz clazz = new Clazz();
clazz.foo();//调用A.foo()
}
}
Optional
注释:
1.所谓的指针,就是java中的对象的引用。比如String s;这个s就是指针。
2.所谓的空指针,就是指针的内容为空,比如上面的s,如果令它指向null,就是空指针。
3.所谓的空指针异常,就是一个指针是空指针,你还要去操作它,既然它指向的是空对象,它就不能使用这个对象的方法。比如上面的s假如为null,你还要用s的方法,比如s.equals( String x);那么就会产生空指针异常。
臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Optional类已经成为Java 8类库的一部分。
Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。更多详情请参考官方文档.。
泛型的改进
1.支持通过方法上下文推断泛型目标类型
2.支持在方法调用链路当中,泛型类型推断传递到最后一个方法

Stream ApI
- 对集合执行批量数据操作
- 仅仅代表着数据流,并没有数据结构
- 串行和并行实现
Stream通用语法

创建Stream
静态方法创建
Stream integerStream = Stream.of(1, 2, 3, 5);
来源Collection
Stream integerStream =nums.stream()
转换Stream
distinct: 对于Stream中包含的元素进行去重操作

聚合Stream
count方法 可使流的结果最终统计,返回int,比如我们计算一下满足18岁的总人数。
int countOfAdult=persons.stream() .filter(p -> p.getAge() > 18) .map(person -> new Adult(person)) .count();
顺序流域并行流
List people = list.getStream.collect(Collectors.toList());
List people = list.getStream.parallel().collect(Collectors.toList());
long t0 = System.nanoTime();
//初始化一个范围100万整数流,求能被2整除的数字,toArray()是终点方法
int a[]=IntStream.range(0, 1_000_000).filter(p -> p % 2==0).toArray();
long t1 = System.nanoTime();
//和上面功能一样,这里是用并行流来计算
int b[]=IntStream.range(0, 1_000_000).parallel().filter(p -> p % 2==0).toArray();
long t2 = System.nanoTime();
//我本机的结果是serial: 0.06s, parallel 0.02s,证明并行流确实比顺序流快
System.out.printf(“serial: %.2fs, parallel %.2fs%n”, (t1 - t0) * 1e-9, (t2 - t1) * 1e-9);
日期和时间API
long t0 = System.nanoTime();
//初始化一个范围100万整数流,求能被2整除的数字,toArray()是终点方法
int a[]=IntStream.range(0, 1_000_000).filter(p -> p % 2==0).toArray();
long t1 = System.nanoTime();
//和上面功能一样,这里是用并行流来计算
int b[]=IntStream.range(0, 1_000_000).parallel().filter(p -> p % 2==0).toArray();
long t2 = System.nanoTime();
//我本机的结果是serial: 0.06s, parallel 0.02s,证明并行流确实比顺序流快
System.out.printf(“serial: %.2fs, parallel %.2fs%n”, (t1 - t0) * 1e-9, (t2 - t1) * 1e-9);
Base64
JDK实现
sun.misc.BASE64Encoder 和 sun.misc.BASE64Decoder
javax.xml.bind.DatatypeConverter
Java 8在java.util
第三方实现
Apache Commons Codec library
Google Guava
net.iharder.Base64
号称Base64编码速度最快的MigBase64
消除永久代(PermGen space)
不再需要调整其大小
当前对象移到 Java 堆或本地内存
JVM参数 -XX:PermSize 和 -XX:MaxPermSize被XX:MetaSpaceSize 和 -XX:MaxMetaspaceSize替换。
Java 8(jdk 1.8)引入了许多重大更新,包括Lambda表达式、Functional接口、Optional、Stream API等。Lambda允许函数作为方法参数,Functional接口可以被转换为lambda表达式。Optional类用于避免空指针异常,而新的Stream API提供了处理集合的新方式,支持串行和并行操作。此外,还改进了泛型和日期时间API,并移除了永久代(PermGen space)。
1755





