〇 前言
关于 java8 的新特性这里有一篇文章比较不错:http://www.importnew.com/11908.html
我选取了我关注的,总结如下:
一、语言新特性
1.1 Lambda表达式与函数式接口
“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),或者把代码看成数据。
语言设计者投入了大量精力来思考如何使现有的函数友好地支持lambda。最终采取的方法是:增加函数式接口的概念。函数式接口就是一个具有一个方法的普通接口。像这样的接口,可以被隐式转换为lambda表达式。如有某个人在接口定义中增加了另一个方法,这时,这个接口就不再是函数式的了,并且编译过程也会失败。为了克服函数式接口的这种脆弱性并且能够明确声明接口作为函数式接口的意图,Java 8增加了一种特殊的注解@FunctionalInterface。通过在接口上添加这个注解,接口将只能有一个方法。
1.2 方法引用
方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
第一种方法引用是构造器引用,它的语法是Class::new。
第二种方法引用是静态方法引用,它的语法是Class::static_method。
第三种方法引用是特定类的任意对象的方法引用,它的语法是Class::method。
第四种方法引用是特定对象的方法引用,它的语法是instance::method。
1.3 接口的默认方法与静态方法
在java8中接口可以用关键字default声明了一个默认方法,还可以声明(并且可以提供实现)静态方法。
private interface Demo {
// Interfaces now allow default methods, the implementer may or
// may not implement (override) them.
default String notRequired() {
return "Default implementation";
}
// Interfaces now allow static methods
static Defaulable create( Supplier< Defaulable > supplier ) {
return supplier.get();
}
}
使用注解的一个限制是相同的注解在同一位置只能声明一次,不能声明多次。Java 8打破了这条规则,引入了重复注解机制,这样相同的注解可以在同一地方声明多次。
二、类库新特性
2.1 stream api
package com.my.test9;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* Title:
* Intention:
*
* Class Name: com.my.test9.StreamApiTest
* Create Date: 2017/8/13 14:55
* Project Name: MyTest
* Company: All Rights Reserved.
* Copyright © 2017
*
*
* author: GaoWei
* 1st_examiner:
* 2nd_examiner:
*
*
* @version 1.0
* @since JDK 1.7
*/
public class StreamApiTest {
public static void main(String[] args) {
StreamApiTest nft = new StreamApiTest();
nft.streamTest();
}
private void streamTest() {
List books = new ArrayList();
books.add(new Book("Java 宝典", "王小强", 45, 300, "中国邮电出版社"));
books.add(new Book("在人间", "某文青", 35, 600, "中国文学出版社"));
books.add(new Book("人民的名义", "周梅森", 25, 384, "北京十月文艺出版社"));
books.add(new Book("白鹿原", "陈忠实", 37, 697, "人民文学出版社"));
books.add(new Book("三体", "刘慈欣", 65, 989, "重庆出版社"));
//查找出价格大于35元的书籍个数
System.out.println(books.stream().filter(p -> p.price > 35).count());
//获取所有的书名
System.out.println(books.stream().map(p -> p.name).collect(Collectors.toList()));
//查找出价格最高的那本书
System.out.println(books.stream().max(Comparator.comparingDouble(p -> p.price)).get());
//获取名称价格map
System.out.println(books.stream().collect(Collectors.toMap(Book::getName, Book::getPrice)));
//获取书名大于2个字,按照价格升序排序的前三本书
System.out.println(books.stream().filter(p -> p.name.length()>2)
.sorted(Comparator.comparingDouble(p -> p.price))
.limit(3)
.collect(Collectors.toList()));
//统计总价
System.out.println(books.stream().map(p -> p.price).reduce((a, b) -> a + b).get());
}
public class Book {
public Book(String name, String author, double price, int pageNum, String publisher) {
this.name = name;
this.author = author;
this.price = price;
this.pageNum = pageNum;
this.publisher = publisher;
}
/**
* 书名
*/
private String name;
/**
* 作者
*/
private String author;
/**
* 价格
*/
private double price;
/**
* 页数
*/
private int pageNum;
/**
* 出版社
*/
private String publisher;
@Override
public String toString() {
return "[name = "+ name + ", author = " + author + ", price=" + price +", pageNum = " + pageNum + ", publisher = " + publisher
+"]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
}
}
2.2 Optional
以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Optional类已经成为Java 8类库的一部分。
Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional的使用可看这里:http://www.importnew.com/22060.html
三、JVM新特性
3.1 PermGen空间
PermGen空间被移除了,取而代之的是Metaspace(JEP 122)。JVM选项-XX:PermSize与-XX:MaxPermSize分别被-XX:MetaSpaceSize与-XX:MaxMetaspaceSize所代替。
那么为什么要取消PermGen空间呢?这个问题恐怕不是一句两句能说得清除的。知乎上点赞数最多的答案(https://www.zhihu.com/question/40543936)混乱不堪,有一篇博客上说:
“permSize:原来的jar包及你自己项目的class存放的内存空间,这部分空间是固定的,启动参数里面-permSize确定,如果你的jar包很多,经常会遇到permSize溢出,且每个项目都会占用自己的permGen空间
改成metaSpaces,各个项目会共享同样的class内存空间,比如两个项目都用了fast-json开源包,在mentaSpaces里面只存一份class,提高内存利用率,且更利于垃圾回收”