Java 各个版本中的新特性
新特性你知道多少?
Java 8
Java 8 中主要的新特性有4个。
Lambda 表达式
Lambda 表达式允许将函数作为一个方法的参数,即把函数作为参数传递进方法中。
示例如下:
public class Lambda {
public static void main(String[] args) {
// 类型声明
MathOperation addition = (int a, int b) -> a + b;
// 不用声明类型
MathOperation subtraction = (a, b) -> 0;
// 大括号中的返回语句
MathOperation multiplication = (int a, int b) -> { return a * b; };
// 没有大括号及返回语句
MathOperation division = (int a, int b) -> a / b;
Lambda lambda = new Lambda();
System.out.println(lambda.operate(1,2,addition));
}
interface MathOperation {
int operation(int a, int b);
}
interface GrecetingService {
void sayMessage(String message);
}
private int operate(int a, int b, MathOperation mathOperation) {
return mathOperation.operation(a, b);
}
}
接口增加默认方法等
在 Java 8 以前,接口中只能有常量和抽象方法,不能含有方法的实现。但是在 Java 8 中,我们可以对接口添加默认实现,还可以实现静态方法。
示例:
public class InterfaceDefault {
public static void main(String[] args) {
}
class LogOracle implements logging {
}
interface logging {
String ORACLE = "Oracle_Database";
String MYSQL = "Mysql_Database";
default void logInfo(String message) {
getConnection();
System.out.println("Log Message : " + "INFO");
closeConnection();
}
static void getConnection() {
System.out.println("Open Database connection");
}
static void closeConnection() {
System.out.println("Close Database connection");
}
}
}
方法引用
方法引用通过方法的名字来指向一个方法.
示例:
public class MethodReference {
public static void main(String[] args) {f
// 方法引用使用一对冒号 :: 来实现
List names = new ArrayList();
names.add("Google");
names.add("Runoob");
names.add("Taobao");
names.add("Baidu");
names.add("Sina");
names.forEach(System.out::println);
}
}
流 Stream
Java 8 API 添加了一个称为流 Stream 的新的抽象,通过使用 Stream 可以提高程序员的生产力,让程序员写出高效、干净、简洁的代码。
流 Stream 将要处理的元素集合看作一种流,流可以在管道中传输,并且可以在管道的节点上进行处理,比如过滤筛选,排序,聚合等。
示例:
public class Stream {
public static void main(String[] args) {
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
System.out.println("列表: " + strings);
long count = strings.stream().filter(string -> string.isEmpty()).count();
System.out.println("空字符串数量为: " + count);
count = strings.stream().filter(string -> string.length() == 3).count();
System.out.println("字符串长度为 3 的数量为: " + count);
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选后的列表: " + filtered);
String collect = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(","));
System.out.println("合并字符串:" + collect);
//*********************//
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> integers = Arrays.asList(1, 2, 13, 4, 15, 6, 17, 8, 19);
List<Integer> squaresList = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
System.out.println("Squares List: " + squaresList);
System.out.println("列表: " + integers);
IntSummaryStatistics stats = integers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
System.out.println("随机数: ");
// 输出10个随机数
Random random = new Random();
for (int i = 0; i < 10; i++) {
System.out.println(random.nextInt());
}
random.ints().limit(10).sorted().forEach(System.out::println);
// 并行处理
count = strings.parallelStream().filter(string -> string.isEmpty()).count();
System.out.println("空字符串的数量为: " + count);
}
}
Java 9
Java 9 中最值得关注的就是引入了模块系统,还有其他一些特性如下。
模块系统
Java 9 引入了模块系统,并且将 JDK 也进行了模块化。在以前,不管我们做什么项目(有可能就是很小的一个demo项目)都需要包含 JDK 中所有的包,这样会导致程序包非常大。将 JDK 模块化后,当用到某些模块时,之引入具体的模块,这样会大大减小程序包。
JDK 9 中一共由 94 个模块组成,通过新增的 jlink
工具可以创建出每个应用独有的 Java 运行时镜像。
交互式工具jshell
Java 9 增加了新特性 jshell
,在 jshell 中可以直接输入表达式并查看执行结果。
当我们需要测试一个方法的运行效果,或是快速的对表达式进行求值时,jshell 都非常实用。
.of() 创建不可变集合
在集合中, java 9 增加了 List.of()、Set.of()、Map.of() 等工厂方法来创建不可变集合。在这之前,如果我们需要创建不可变集合,需要借助 Collections.unmodifiableSet() 等方法来实现。
接口支持私有方法
在 Java 8 中,接口引入了新的支持 一一 默认方法和静态方法。
在 Java 9 中,接口又引入了对私有方法的支持。
示例:
interface logging {
String ORACLE = "Oracle_Database";
String MYSQL = "Mysql_Database";
private void log(String message, String prefix) {
getConnection();
System.out.println("Log Message : " + prefix);
closeConnection();
}
default void logInfo(String message) {
log(message, "INFO");
}
static void getConnection() {
System.out.println("Open Database connection");
}
static void closeConnection() {
System.out.println("Close Database connection");
}
}
更好的 Try-with-resource 体验
Java 7 引入了 Try-with-resource,使得我们可以更方便地对资源进行关闭,但是我们必须得对资源对象进行声明。
Java 9 中去除了这一限制,使得对资源的管理更加方便。
示例:
private static String beforeJava9(String message) throws IOException {
Reader inputString = new StringReader(message);
BufferedReader br = new BufferedReader(inputString);
try (BufferedReader br1 = br) {
return br1.readLine();
}
}
private static String Java9(String message) throws IOException {
Reader inputString = new StringReader(message);
BufferedReader br = new BufferedReader(inputString);
try (br) {
return br.readLine();
}
}
Java 10
局部变量类型推断 var
Java 10 中我觉得最值得说的就属局部变量类型推断 var 了,它能够帮助我们更加快速地编写简洁的代码。但是使用 var 使得我们不容易分辨变量的类型,利弊各有吧。
示例:
public class LocalVariableTypeInference {
public static void main(String[] args) {
var list = new ArrayList<String>();
list.add("2");
System.out.println(list.toString());
var stream = list.stream();
System.out.println(stream.toString());
}
}
Java 11
var 支持 Lambda
Java 10 虽然引入了 var 保留字,但是其不能在 Lambda 中声明使用,在 Java 11 中克服了这一弊端。
示例:
// (var x, var y) -> x.process(y)
// 等价于
// (x, y) -> x.process(y)
标准化的 HTTP Client API
Java 11 中将 HttpClient 变成了原生的,在这之前,我们使用 HttpClient时,需要引入 apache 的包。