Java各版本特征
约 2373 字大约 8 分钟
Java8 新特性
1. 函数式接口
package model3.unit10;
// 函数式接口:只有一个抽象方法的接口:SAM
// 函数式接口注解:@FunctionalInterface
@FunctionalInterface
public interface Java03 {
void m1();
}
class Java04 {
public static void main(String[] args) {
// 函数式接口的使用
Java03 a = () -> {
System.out.println(100);
System.out.println(200);
};
a.m1();
}
}
@FunctionalInterface
interface Java05<T> {
void m(int a, double b);
}
2. 数组集合之间转换
package model3.unit10;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Java06 {
public static void main(String[] args) {
// 数组转换为集合
String[] arr = {"张三", "李四"};
// 通过数组类方法转换
List<String> list = Arrays.asList(arr);
list.forEach(System.out::println);
List<String> list2 = Arrays.asList("王五", "赵六");
list2.forEach(System.out::println);
// 集合转数组
List<String> list3 = new ArrayList<>();
list3.add("aa");
list3.add("bb");
// 注意:
String[] brr = list3.toArray(new String[0]);
for (String s : brr) {
System.out.println(s);
}
}
}
3. Stream流
package model3.unit10;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Java07 {
public static void main(String[] args) {
// JDK1.8特性:Stream流
// Stream流不存储数据、处理数据的逻辑、条件、筛选等功能。
// Stream流中有很多功能的方法帮助我们解决问题。(类似SQL)
// 集合转换为Stream流
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
// Stream流.forEach遍历
list.stream().forEach(System.out::println);
// Stream流去重
List<Integer> a = list.stream().distinct().collect(Collectors.toList());
a.forEach(System.out::println);
// Stream流截取
List<Integer> b = list.stream().limit(3).collect(Collectors.toList());
b.forEach(System.out::println);
// Stream流跳过
List<Integer> c = list.stream().skip(2).collect(Collectors.toList());
c.forEach(System.out::println);
// Stream流同时调用跳过和截取
List<Integer> d = list.stream().skip(1).limit(3).distinct().collect(Collectors.toList());
d.forEach(System.out::println);
// Stream流过滤
List<Integer> e = list.stream().filter(x -> (x % 2 == 0)).collect(Collectors.toList());
e.forEach(System.out::println);
List<Integer> f = list.stream().filter(x -> (x >= 2 && x <= 4)).collect(Collectors.toList());
f.forEach(System.out::println);
// Stream流合并
long i = Stream.concat(list.stream(), list.stream()).count();
System.out.println(i);
// List集合转换为Map集合(k,v)
List<Person> personList = new ArrayList<>();
personList.add(new Person("张三", 30));
personList.add(new Person("李四", 40));
personList.forEach(System.out::println);
Map<String, Integer> map = personList.stream().collect(Collectors.toMap(Person::getName, Person::getAge));
map.forEach((k, v) -> {
System.out.println(k + "\t" + v);
});
}
}
class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
4. List转换Map
package model3.unit10;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Java08 {
public static void main(String[] args) {
// List集合转换为Map集合(k,v)
List<Person> list = new ArrayList<>();
list.add(new Person("张三", 30));
list.add(new Person("李四", 40));
list.add(new Person("李四", 50));
// (1)基本List转Map(key->value)
Map<String, Integer> map = list.stream().collect(Collectors.toMap(Person::getName, Person::getAge));
map.forEach((k, v) -> {
System.out.println(k + "\t" + v);
});
// (2)基本List转Map(key->value)
Map<String, Person> personMap = list.stream().collect(Collectors.toMap(Person::getName, person -> person));
personMap.forEach((k, v) -> {
System.out.println(k + "\t" + v);
});
// (3)当有重复key时,选择哪个value
Map<String, Integer> ageMap = list.stream().collect(Collectors.toMap(Person::getName, Person::getAge, (key1, key2) -> key1));
ageMap.forEach((k, v) -> {
System.out.println(k + "\t" + v);
});
}
}
class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Java9/10新特性
1. 集合增强
import java.util.ArrayList;
import java.util.List;
public class Java01 {
public static void main(String[] args) {
// 集合增强快速创建不可变集合
// 自 Java 9 开始
// 增加了List.of()、Set.of()、Map.of() 和 Map.ofEntries()工厂方法创建不可变集合
// 使用 of() 创建的集合为不可变集合、不能进行添加删除替换 排序等操作
// 不然会报 java.lang.UnsupportedOperationException 异常
// 自 Java 10 开始
// List,Set,Map 提供了静态方法copyOf()返回入参集合的一个不可变拷贝。
var list = List.of("Java", "Python", "C");
var copy = List.copyOf(list);
System.out.println(list == copy); // true
var list2 = new ArrayList<String>();
var copy2 = List.copyOf(list2);
System.out.println(list2 == copy2); // false
}
}
2. 字符串增强
public class Java02 {
public static void main(String[] args) {
// Java 8 及之前的版本,String 一直是用 char[] 存储。
// 在 Java 9 之后,String 的实现改用 byte[] 数组存储字符串,节省了空间。
String s = "abc";
}
}
3. Stream流增强
import java.util.List;
public class Java03 {
public static void main(String[] args) {
// Stream
// takeWhile() 方法可以从 Stream 中依次获取满足条件的元素
// 直到不满足条件为止结束获取。
List<Integer> integerList = List.of(11, 33, 66, 8, 9, 13);
integerList.stream().takeWhile(x -> x < 50).forEach(System.out::println);// 11 33
// dropWhile() 方法的效果和 takeWhile() 相反。
List<Integer> integerList2 = List.of(11, 33, 66, 8, 9, 13);
integerList2.stream().dropWhile(x -> x < 50).forEach(System.out::println);// 66 8 9 13
}
}
4. 进程API
import java.lang.ProcessHandle.Info;
public class Java04 {
public static void main(String[] args) {
// 进程 API
// Java 9 增加了 java.lang.ProcessHandle 接口来实现对原生进程进行管理
// 尤其适合于管理长时间运行的进程。
// 获取当前正在运行的 JVM 的进程
ProcessHandle currentProcess = ProcessHandle.current();
// 输出进程的 id
System.out.println(currentProcess.pid());
// 输出进程的信息
System.out.println(currentProcess.info());
}
}
5. 局部变量推断
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Java05 {
public static void main(String[] args) {
// Java 10 提供了 var 关键字声明局部变量。
var id = 0;
var list = new ArrayList<>();
var list2 = List.of(1, 2, 3);
var map = new HashMap<String, String>();
var numbers = List.of("a", "b", "c");
for (var n : list)
System.out.print(n + " ");
// var 关键字只能用于带有构造器的局部变量和 for 循环中。
// var count=null; //❌编译不通过,不能声明为 null
// var r = () -> Math.random(); //❌编译不通过,不能声明为 Lambda表达式
// var array = {1,2,3}; //❌编译不通过,不能声明数组
}
}
Java11 新特性
1. 字符串增强
import java.util.List;
import java.util.stream.Collectors;
public class Java01 {
public static void main(String[] args) {
// String 增强
// 判断字符串是否为空
boolean a = " ".isBlank(); // true
System.out.println(a);
// 去除字符串首尾空格
String b = " Java ".strip(); // "Java"
System.out.println(b);
// 去除字符串首部空格
String c = " Java ".stripLeading(); // "Java "
System.out.println(c);
// 去除字符串尾部空格
String d = " Java ".stripTrailing(); // " Java"
System.out.println(d);
// 重复字符串多少次
String e = "Java".repeat(3); // "JavaJavaJava"
System.out.println(e);
// 返回由行终止符分隔的字符串集合。
long f = "A\nB\nC".lines().count(); // 3
System.out.println(f);
List<String> collect = "A\nB\nC".lines().collect(Collectors.toList());
collect.forEach(System.out::println);
}
}
2. Stream流增强
import java.util.List;
public class Java02 {
public static void main(String[] args) {
// Stream 加强
List<String> names = List.of("Alice", "Bob", "Charlie");
// Java 11之前需要使用collect(Collectors.toList())
List<String> upperCaseNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
// Java 11中使用toList()方法
List<String> upperCaseNames2 = names.stream()
.map(String::toUpperCase)
.toList();
}
}
3. Lambda增强
import java.util.function.Function;
public class Java03 {
public static void main(String[] args) {
// Lambda
// 在Java 11之前
Function<Integer, String> function = (Integer x) -> String.valueOf(x);
// 使用Lambda参数类型推断
Function<Integer, String> function2 = (x) -> String.valueOf(x);
}
}
Java12/13 新特性
1. IO流增强
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class Java01 {
public static void main(String[] args) throws IOException {
// Files 增强(文件比较)
// Java 12 添加了以下方法来比较两个文件
// mismatch() 方法用于比较两个文件,并返回第一个不匹配字符的位置
// 如果文件相同则返回 -1L。
File tempFile1 = File.createTempFile("file1", ".txt", new File("d:/"));
File tempFile2 = File.createTempFile("file2", ".txt", new File("d:/"));
Files.writeString(tempFile1.toPath(), "Java 12 Article");
Files.writeString(tempFile2.toPath(), "Java 12 Article");
long mismatch = Files.mismatch(tempFile1.toPath(), tempFile2.toPath());
System.out.println(mismatch);
File tempFile3 = File.createTempFile("file3", ".txt", new File("d:/"));
File tempFile4 = File.createTempFile("file4", ".txt", new File("d:/"));
Files.writeString(tempFile3.toPath(), "Java 12 Article");
Files.writeString(tempFile4.toPath(), "Java 12 Tutorial");
long mismatch2 = Files.mismatch(tempFile3.toPath(), tempFile4.toPath());
System.out.println(mismatch2);
}
}
2. 字符串增强
public class Java02 {
public static void main(String[] args) {
// instanceof 模式匹配
// 之前的版本中,我们需要显示地对对象进行类型转换。
Object obj = "我是字符串";
if (obj instanceof String) {
String str = (String) obj;
System.out.println(str);
}
// 新版的 instanceof 可以在判断是否属于具体的类型同时完成转换。
Object obj2 = "我是字符串";
if (obj2 instanceof String str) {
System.out.println(str);
}
}
}
3. 字符串增强
public class Java03 {
public static void main(String[] args) {
// Java 13 支持两个 """ 符号中间的任何内容都会被解释为字符串的一部分
// 包括换行符
String json = """
{
"name": "mkyong",
"age": 38
}
""";
System.out.println(json);
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
System.out.println(query);
}
}
Java14/15 新特性
1. record关键字
public class Java01 {
public static void main(String[] args) {
// 14 record 关键字
Rectangle r = new Rectangle(1.5F, 2.5F);
System.out.println(r);
Rectangle2 r2 = new Rectangle2(1.5F, 2.5F);
System.out.println(r2);
}
}
/**
* 这个类具有两个特征
* 1. 所有成员属性都是final
* 2. 全部方法由构造方法,和两个成员属性访问器组成(共三个)
* 那么这种类就很适合使用record来声明
*/
final class Rectangle {
final double length;
final double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
double length() { return length; }
double width() { return width; }
}
/**
* 1. 使用record声明的类会自动拥有上面类中的三个方法
* 2. 在这基础上还附赠了equals(),hashCode()方法以及toString()方法
* 3. toString方法中包括所有成员属性的字符串表示形式及其名称
*/
record Rectangle2(float length, float width) { }
2. 密封类
public class Java02 {
public static void main(String[] args) {
// 密封类(Sealed Classes) 是 Java 15 中的一个预览新特性。
// 没有密封类之前如果想让一个类不能被继承和修改可以使用final 关键字
// 这种方式不太灵活,直接把一个类的继承和修改渠道给堵死了。
// 密封类可以对继承或者实现它们的类进行限制
// 这样这个类就只能被指定的类继承。
}
}
// 抽象类 Person 只允许 E 和 F 继承。
// 抽象类 Person 只允许 Employee 和 Manager 继承。
abstract sealed class Person permits Employee, Manager {
//...
}
// 另外,任何扩展密封类的类本身都必须声明为 sealed、non-sealed 或 final
final class Employee extends Person {
}
non-sealed class Manager extends Person {
}
特别说明:
Java 17 是继 Java 8 以来最重要的长期支持(LTS)版本,是 Java 社区八年努力的成果。
Spring 6.x 和 Spring Boot 3.x 最低支持的就是 Java 17。