JDK8~13新特性概览
JDK8
1. 接口default 与 static 关键字
/**
* jdk8中接口可以使用声明default和static修饰的方法
* static修饰的方法和普通的方法一样,可以被直接调用
* default修饰的方法有方法体,就和普通的方法一样,可以被重写,有点像抽象类的方法一样,但是java是单继承多实现的
*/
public interface Today { void dream(); void striver(); default void victory(){
System.out.println("未来");
} static void test(){
System.out.println("接口里的静态方法");
} // jdk9 中还新增了private方法
private void test3() {
System.out.println("私有方法");
};
}
2. base64 api
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.util.Base64;
/**
* Base64是⽹络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是
* 一种基于64个可打印字符来表示二进制数据的方法 基于64个字符A-Z,a-z,0-9,+,/的编码方式,
* 是一种能将任意二进制数据用64种字元组合成字符串的方法,
*/
public class Main { public static void main(String[] args) throws Exception {
/**
* jdk8以前的写法
* 编码和解码的效率⽐较差,公开信息说以后的版本会取消这个⽅法
*/
BASE64Encoder encoder = new BASE64Encoder();
BASE64Decoder decoder = new BASE64Decoder();
byte[] textByte = "圣魔导师".getBytes("UTF-8");
//编码
String encodedText = encoder.encode(textByte);
System.out.println(encodedText);//5Zyj6a2U5a+85biI
//解码
System.out.println(new String(decoder.decodeBuffer(encodedText),"UTF-8"));//圣魔导师 /**
* jdk8的写法
* 编解码销量远⼤于 sun.misc 和 Apache Commons Codec,可以自己动手压测一下速度
*/
Base64.Decoder decoder2 = Base64.getDecoder();
Base64.Encoder encoder2 = Base64.getEncoder();
byte[] textByte2 = "圣魔导师".getBytes("UTF-8");
//编码
String encodedText2 = encoder2.encodeToString(textByte2);
System.out.println(encodedText);//5Zyj6a2U5a+85biI
//解码
System.out.println(new String(decoder2.decode(encodedText2), "UTF-8"));//圣魔导师
}
}
3. 简便的日期工具类
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* SimpleDateFormat,Calendar等类的 API设计⽐较差,⽇期/时间对象⽐较,加减麻烦,Date 还是⾮线程安全的;
* 所以 Java 8通过发布新的 java.time里的工具类来简化处理,如⽇期/时间的⽐较,加减,格式化。
* 核⼼类:
* LocalDate:不包含具体时间的⽇期。
* LocalTime:不含⽇期的时间。
* LocalDateTime:包含了⽇期及时间。
*/
public class Main {
public static void main(String[] args) throws Exception {
Main main = new Main();
LocalTime localTime = LocalTime.now();
System.out.println("现在时间:"+localTime);// 现在时间:23:00:49.476
System.out.println("============= localTime常用方法 =============");
main.localTime();
System.out.println("============= localDateTime常用方法 =============");
main.localDateTime();
}
public void localTime(){
LocalDate today = LocalDate.now();
System.out.println("今天⽇期:" + today);// 今天⽇期:2019-11-07
//获取年,⽉,⽇,周⼏
System.out.println("现在是哪年:"+today.getYear());// 现在是哪年:2019
System.out.println("现在是哪⽉(英文):"+today.getMonth());// 现在是哪⽉(英文):NOVEMBER
System.out.println("现在是哪⽉(数字):"+today.getMonthValue());// 现在是哪⽉(数字):11
System.out.println("现在是⼏号:"+today.getDayOfMonth());// 现在是⼏号:7
System.out.println("现在是周⼏:"+today.getDayOfWeek());// 现在是周⼏:THURSDAY
//加减年份, 加后返回的对象才是修改的,旧的依然是旧的
LocalDate changeDate = today.plusYears(1);
System.out.println("加后是哪年:"+changeDate.getYear());// 加后是哪年:2020
System.out.println("旧的是哪年:"+today.getYear());// 旧的是哪年:2019
//日期比较
System.out.println("isAfter:"+changeDate.isAfter(today));// isAfter:true
/*
//getYear() int 获取当前⽇期的年份
//getMonth() Month 获取当前⽇期的⽉份对象
//getMonthValue() int 获取当前⽇期是第⼏⽉
//getDayOfWeek() DayOfWeek 表示该对象表示的⽇期是星期⼏
//getDayOfMonth() int 表示该对象表示的⽇期是这个⽉第⼏天
//getDayOfYear() int 表示该对象表示的⽇期是今年第⼏天
//withYear(int year) LocalDate 修改当前对象的年份
//withMonth(int month) LocalDate 修改当前对象的⽉份
//withDayOfMonth(int dayOfMonth) LocalDate 修改当前对象在当⽉的⽇期
//plusYears(long yearsToAdd) LocalDate 当前对象增加指定的年份数
//plusMonths(long monthsToAdd) LocalDate 当前对象增加指定的⽉份数
//plusWeeks(long weeksToAdd) LocalDate 当前对象增加指定的周数
//plusDays(long daysToAdd) LocalDate 当前对象增加指定的天数
//minusYears(long yearsToSubtract) LocalDate 当前对象减去指定的年数
//minusMonths(long monthsToSubtract) LocalDate 当前对象减去注定的⽉数
//minusWeeks(long weeksToSubtract) LocalDate 当前对象减去指定的周数
//minusDays(long daysToSubtract) LocalDate 当前对象减去指定的天数
//compareTo(ChronoLocalDate other) int ⽐较当前对象和other对象在时间上的⼤⼩,返回值如果为正,则当前对象时间较晚,
//isBefore(ChronoLocalDate other) boolean ⽐较当前对象⽇期是否在other对象⽇期之前
//isAfter(ChronoLocalDate other) boolean ⽐较当前对象⽇期是否在other对象⽇期之后
//isEqual(ChronoLocalDate other) boolean ⽐较两个⽇期对象是否相等
*/
} public void localDateTime(){
// DateTimeFormatter是线程安全的SimpleDateFormat
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);// 2019-11-07T23:12:29.056
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String ldtStr = dtf.format(ldt);
System.out.println(ldtStr);// 2019-11-07 23:12:29
// 获取指定的⽇期时间对象
LocalDateTime ldt2 = LocalDateTime.of(2020, 11, 11, 8, 20, 30);
System.out.println(ldt2);// 2020-11-11T08:20:30
// 计算⽇期时间差 java.time.Duration
LocalDateTime today = LocalDateTime.now();
System.out.println(today);// 2019-11-07T23:12:29.070
LocalDateTime changeDate = LocalDateTime.of(2020,10,1,10,40,30);
System.out.println(changeDate);// 2020-10-01T10:40:30
Duration duration = Duration.between( today,changeDate);//第⼆个参数减第⼀个参数
System.out.println(duration.toDays());//两个时间差的天数
System.out.println(duration.toHours());//两个时间差的⼩时数
System.out.println(duration.toMinutes());//两个时间差的分钟数
System.out.println(duration.toMillis());//两个时间差的毫秒数
System.out.println(duration.toNanos());//两个时间差的纳秒数
}
}
4. lambda 与 函数式编程
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 面向对象编程是对数据的抽象(各种各样的POJO类);
* 函数式编程则是对行为的抽象(将行为作为一个参数进行传递)
* 所谓的函数编程,即可理解是将一个函数(也称为“行为”)作为⼀个参数进行传递
*
* lambda表达式 使⽤场景:接口中只能有一个方法,
* 比如Runnable接口里的run方法;Comparator接口里的compareTo方法
* Lambda 表达式的实现方式在本质是以匿名内部类的方式进行实现的
*/
public class Main {
public static void main(String[] args) throws Exception { new Thread(new Runnable() {
@Override
public void run() {
System.out.println("jdk8以前创建线程");
}
});
//()对应run()没有一个参数,->后面是方法体内容
//如果{}中的代码只有⼀行,⽆论有返回值,可以省略{}、return、分号,其他则需要加上
new Thread(()-> System.out.println("lambda表达式创建线程")); List<String> list = Arrays.asList("a","c","d","b","e");
// jdk8以前排序
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
// lambda表达式排序
//,前面的对应接口前面的参数,a b 对应compare里面的参数
Collections.sort(list,(a,b)->b.compareTo(a));
}
} ================== 自定义函数是编程(1) ==================== /**
* 像Runnable接口一样用FunctionalInterface注解修饰
* 加了这个注解后,接口里面必须有且只能有一个方法
*/
@FunctionalInterface
public interface Test1<R,T>{ // R表示返回值,T表示参数类型,t1 t2是具体参数
R operator(T t1, T t2);
} public class Compute {
/**
* 定义一个函数方法
* 需要传入a和b两个参数,
* 后面的Test1<Integer,Integer> of就是传入的一个函数(行为),of是随便起的一个别名
*/
public static Integer operator(Integer a,Integer b,Test1<Integer,Integer> of){
return of.operator(a,b);
}
} public class Main {
public static void main(String[] args) throws Exception {
System.out.println(Compute.operator(2,3,(a,b)-> a+b));
System.out.println(Compute.operator(2,3,(a,b)-> a-b));
System.out.println(Compute.operator(2,3,(a,b)-> a*b));
System.out.println(Compute.operator(2,3,(a,b)-> a/b));
}
} ================== 自定义函数是编程(2) ==================== @FunctionalInterface
public interface Test2{ void test();
} public class Main {
public static void main(String[] args) throws Exception {
Main.casesc(()-> System.out.println("函数式编程案例二"));
} public static void casesc(Test2 t){
t.test();
}
}
5. 四大核心函数式接口
Lambda表达式必须先定义接口,创建相关方法之后才能调用,这样做十分不便,其实java8已经内置了许多接口, 例如下面四个功能型接口.所有标注@FunctionalInterface注解的接口都是函数式接口
public class Main {
public static void main(String[] args) throws Exception {
Consumer<String> c1 = obj->System.out.println(obj+": 调⽤用短信接⼝口发送短信,或者打印⽇日志");
c1.accept("订单id—001"); Consumer<List> c2 = obj->{
if(obj==null || obj.size()<1)return;
obj.forEach(o-> System.out.println(o));
};
List<Integer> list = Arrays.asList(2,4,0,8,9,7);
c2.accept(list);
}
}
Consumer 消费型接口:有入参,无返回值。适用场景:因为没有出参,常⽤用于打印、发送短信等消费动作
public class Main {
public static void main(String[] args) throws Exception {
Student student = newStudent();
System.out.println(student);
} public static Student newStudent(){
Supplier<Student> supplier = ()-> {
Student student = new Student();
student.setName("默认名称");
return student;
};
return supplier.get();
}
} class Student{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
Supplier 供给型接口:无入参,有返回值。适用场景:泛型一定和方法的返回值类型是同一种类型,并且不需要传入参数,例如 无参的工厂方法
Function:只能接受一个参数 用法一(用一个类实现接口里面的逻辑,然后直接调用) public class FunctionObj implements Function { @Override
public Object apply(Object o) {
return "对参数:"+o+"经过处理后返回结果";
}
} public class Main {
public static void main(String[] args) throws Exception {
System.out.println(test("hello",new FunctionObj()));
} public static String test(String a ,FunctionObj functionObj){
return functionObj.apply(a).toString();
}
} 用法二(左边规定好参数和返回值类型,右边写方法体具体逻辑) public class Main {
public static void main(String[] args) throws Exception {
Function<Integer,Integer> func = p->{
return p*100;
};
System.out.println(func.apply(12)); Function<Integer,Boolean> function = a->a<100;
System.out.println(function.apply(97));
}
} ================================================================= BiFunctionObj:能接受两个参数 // 用法一 public class BiFunctionObj implements BiFunction {
@Override
public Object apply(Object o, Object o2) {
return (Integer.valueOf(o.toString())+Integer.valueOf(o2.toString()));
}
} public class Main {
public static void main(String[] args) throws Exception {
System.out.println(test(2,5,new BiFunctionObj()));
} public static Integer test(Integer a,Integer b, BiFunctionObj func){
return Integer.valueOf(func.apply(a,b).toString());
}
}
// 用法二 public class Main {
public static void main(String[] args) throws Exception {
BiFunction<Integer, Integer,Boolean> func1 = (a,b)->{
return a>b;
};
System.out.println(func1.apply(1,5)); BiFunction<String, String,String> func2 = (a,b)->a+b;
System.out.println(func2.apply("hellow","world"));
}
}
Function与BiFunctionObj 函数型接口:有入参,有返回值。适用场景:传入参数经过函数的计算返回另一个值
public class Main {
public static void main(String[] args) throws Exception {
Predicate<Integer> predicate = a->a>10; List<Integer> list = Arrays.asList(1,54,9,34,3);
for(Integer l : list){
if(predicate.test(l)) System.out.println(l);
}
}
}
Predicate 断言型接口:有入参,有返回值,返回值类型确定是boolean。适用场景:接收一个参数,用于判断是否满一定的条件,过滤数据
6. 流操作
/**
* Stream:通过将集合转换为这么⼀种叫做 “流”的元素队列,能够对集合中的每个元素进行任意操作。总共分为4个步骤:
* 数据元素便是原始集合:如List、Set、Map等
* 生成流:可以是串行流stream() 或者并行流 parallelStream()
* 中间操作:可以是 排序,聚合,过滤,转换等
* 终端操作:统一收集返回一个流
*
* 一般都采用stream,因为集合操作一般里面就几百条数据,多线程的并行流效率不一定就高,还会出现线程安全问题
*/
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("张麻子","李蛋","王二狗","Angell");
List<Student> users = Arrays.asList(new Student("张三", 23),
new Student("赵四", 24),
new Student("二狗", 23),
new Student("田七", 22),
new Student("皮特", 20),
new Student("Tony", 20),
new Student("二柱子", 25));
/**
* map:对集合的每个对象做处理
*/
List<String> collect = list.stream().map(obj->"哈哈"+obj).collect(Collectors.toList());
list.forEach(obj->System.out.println(obj));
System.out.println("----------------");
collect.forEach(obj->System.out.println(obj));
/**
* filter:boolean判断,用于条件过滤
*/
System.out.println("----------------");
Set<String> set = list.stream().filter(obj->obj.length()>2).collect(Collectors.toSet());
set.forEach(obj->System.out.println(obj));
/**
* sorted:对流进行自然排序
*/
System.out.println("----------------");
Set<String> sorteds = list.stream().sorted().collect(Collectors.toSet());
sorteds.forEach(obj->System.out.println(obj));
// 自定义排序规则
// 根据长度排序(正序)
System.out.println("----------------");
List<String> resultList = list.stream().sorted(Comparator.comparing(obj -> obj.length())).collect(Collectors.toList());
resultList.forEach(obj->System.out.println(obj));
System.out.println("----------------");
// 根据长度排序(倒序)
List<String> resultList2 = list.stream().sorted(Comparator.comparing(obj -> obj.length(),Comparator.reverseOrder())).collect(Collectors.toList());
resultList2.forEach(obj->System.out.println(obj));
System.out.println("----------------");
// 手动指定排序规则(根据年龄大小排序)
List<Student> collect2 = users.stream().sorted(
Comparator.comparing(Student::getAge,(x,y)->{
if(x>y) {
return 1;
}else {
return -1;
}
})
).collect(Collectors.toList());
collect2.forEach(obj->System.out.println(obj.getAge()+" : "+obj.getProvince()));
/**
* limit:截取包含指定数量的元素
*/
System.out.println("----------------");
List<String> collect3 = list.stream().limit(2).collect(Collectors.toList());
collect3.forEach(obj->System.out.println(obj));
/**
* allMatch:匹配所有元素,只有全部符合才返回true
*/
System.out.println("----------------");
boolean flag = list.stream().allMatch(obj->obj.length()>2);
System.out.println(flag);
System.out.println("----------------");
/**
* anyMatch:匹配所有元素,至少一个元素满足就为true
*/
boolean flag2 = list.stream().anyMatch(obj->obj.length()>2);
System.out.println(flag2);
System.out.println("----------------");
/**
* max和min:最大值和最小值
*/
Optional<Student> max = users.stream().max(Comparator.comparingInt(Student::getAge));
System.out.println(max.get().getAge()+" : "+max.get().getProvince());
System.out.println("----------------");
Optional<Student> min = users.stream().min((s1, s2)->Integer.compare(s1.getAge(),s2.getAge()));
System.out.println(min.get().getAge()+" : "+min.get().getProvince()); /**
* reduce:对Stream中的元素进行计算后返回一个唯一的值
*/ // 计算所有值的累加
int value = Stream.of(1, 2, 3, 4, 5).reduce((item1, item2) -> item1 + item2).get();
// 100作为初始值,然后累加所有值
int value2 =Stream.of(1, 2, 3, 4, 5).reduce(100, (sum, item) -> sum + item);
// 找出最大值
int value3 =Stream.of(1, 4, 5, 2, 3).reduce((x,y)->x>y?x:y).get(); System.out.println(value);
System.out.println(value2);
System.out.println(value3);
}
} class Student {
private String province;
private int age;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String province, int age) {
this.age = age;
this.province = province;
}
}
7. 终端操作收集器:Collector
/**
* 数据结构收集:Collectors
*/
public class Main {
public static void main(String[] args) throws Exception {
List<String> data = Arrays.asList("张三","王五","李四");
List<String> list = data.stream().collect(Collectors.toList());
Set<String> set = data.stream().collect(Collectors.toSet());
LinkedList<String> linkedList = data.stream().collect(Collectors.toCollection(LinkedList::new));
System.out.println(list);
System.out.println(set);
System.out.println(linkedList);
/*
Collectors.toMap()
Collectors.toSet()
Collectors.toCollection() :⽤用⾃自定义的实现Collection的数据结构收集
Collectors.toCollection(LinkedList::new)
Collectors.toCollection(CopyOnWriteArrayList::new)
Collectors.toCollection(TreeSet::new)
*/
}
} //============================================================ /**
* 拼接函数:joining
*/
public class Main {
public static void main(String[] args) throws Exception {
List<String> list = Arrays.asList("springBoot","springCloud","netty");
String result1 = list.stream().collect(Collectors.joining());
String result2 = list.stream().collect(Collectors.joining("——"));
String result3 = list.stream().collect(Collectors.joining("—", "【","")); String result4 = Stream.of("hello", "world").collect(Collectors.joining("—", "【", "】")); System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
System.out.println(result4);
}
} //============================================================ /**
* 分组:partitioningBy
*/
public class Main {
public static void main(String[] args) throws Exception {
List<String> list = Arrays.asList("sdfsdf","xxxx","bbb","bbb");
Map<Boolean, List<String>> collect = list.stream().collect(Collectors.partitioningBy(obj -> obj.length() > 3));
System.out.println(collect);
}
} //============================================================ /**
* 分组:group by
* 统计:counting
*/
public class Main {
public static void main(String[] args) throws Exception {
List<Student> students = Arrays.asList( new Student("⼴东", 23),
new Student("⼴东", 24),
new Student("⼴东", 23),
new Student("北京", 22),
new Student("北京", 20),
new Student("北京", 20),
new Student("海南", 25));
// 通过名称分组
Map<String, List<Student>> listMap = students.stream().collect(Collectors.groupingBy(obj -> obj.getProvince()));
listMap.forEach((key, value) -> {
System.out.println("========");
System.out.println(key);
value.forEach(obj -> {
System.out.println(obj.getAge());
});
});
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
// 根据名称分组,并统计每个分组的个数
Map<String, Long> map = students.stream().collect(Collectors.groupingBy(Student::getProvince, Collectors.counting()));
map.forEach((key,value)->{
System.out.println(key+"省人数有"+value);
});
}
} class Student {
private String province;
private int age;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String province, int age) {
this.age = age;
this.province = province;
}
} //============================================================ /**
* 统计函数:summarizing
*/
public class Main {
public static void main(String[] args) throws Exception {
List<Student> students = Arrays.asList( new Student("⼴东", 23),
new Student("⼴东", 24),
new Student("⼴东", 23),
new Student("北京", 22),
new Student("北京", 20),
new Student("北京", 20),
new Student("海南", 25));
// summarizingInt; summarizingLong; summarizingDouble
IntSummaryStatistics summaryStatistics = students.stream().collect(Collectors.summarizingInt(Student::getAge));
System.out.println("平均值:" + summaryStatistics.getAverage());
System.out.println("人数:" + summaryStatistics.getCount());
System.out.println("最大值:" + summaryStatistics.getMax());
System.out.println("最小值:" + summaryStatistics.getMin());
System.out.println("总和:" + summaryStatistics.getSum());
}
} /**
* reduce:对Stream中的元素进行计算后返回一个唯一的值
*/
// 计算所有值的累加
int value = Stream.of(1, 2, 3, 4, 5).reduce((item1, item2) -> item1 + item2).get();
// 100作为初始值,然后累加所有值
int value2 =Stream.of(1, 2, 3, 4, 5).reduce(100, (sum, item) -> sum + item);
// 找出最大值
int value3 =Stream.of(1, 4, 5, 2, 3).reduce((x,y)->x>y?x:y).get(); System.out.println(value);
System.out.println(value2);
System.out.println(value3);
JDK9
1. try-with-resource
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream; public class Main { public static void main(String[] args) throws Exception {
String path = "/Users/jack/Desktop/t.txt"; /**
* jdk 1.7以前关闭资源一般是在finally里面操作的
*/
OutputStream out = new FileOutputStream(path);
try {
out.write(("一壶漂泊,浪迹天涯难入喉;你走之后,酒暖回忆思念瘦").getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
} /**
* jdk1.7的时候,可以在try()里声明资源,会在try-catch代码块结束后自动关闭掉。
* try结束后自动调用的close方法,这个动作会早于finally里调用的方法
* bu管是否出现异常,try()里的实例都会被调用close方法
* try里面可以声明多个自动关闭的对象,越早声明的对象,会越晚被close掉
*/
try (OutputStream out2 = new FileOutputStream(path);){
out2.write(("一壶漂泊,浪迹天涯难入喉;你走之后,酒暖回忆思念瘦").getBytes());
} catch (Exception e) {
e.printStackTrace();
} /**
* jdk1.9之后,对try()做了改进,在try外进行初始化,在括号内引用
*/
OutputStream out3 = new FileOutputStream(path);
try (out3) {
out3.write(("一壶漂泊,浪迹天涯难入喉;你走之后,酒暖回忆思念瘦").getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. stream
public class Main {
/**
* jdk9中的Stream流新增了两个api
*/
public static void main(String[] args) throws Exception {
/**
* takeWhile:遍历每个对象,直到遇到第⼀个false时,返回前面所有元素,如果没有false,将返回⼀一个空的 Stream
*/
List<String> list1 = List.of("springboot","java","html","","git").stream()
.takeWhile(obj->!obj.isEmpty()).collect(Collectors.toList());
System.out.println(list1); /**
* dropWhile:与takeWhile相反
*/
List<String> list2 = List.of("springboot","java","html","","git").stream()
.dropWhile(obj->!obj.isEmpty()).collect(Collectors.toList());
System.out.println(list2);
}
}
3. of创建只读集合
public class Main { public static void main(String[] args) throws Exception {
/**
* JDK9之前创建只读集合
*/
List<String> list = new ArrayList<String>();
list.add("张三");
list.add("李四");
list.add("王五");
list.remove(0);
System.out.println(list);
//设置为只读List集合
// unmodifiableMap(map); unmodifiableMap(set);
list = Collections.unmodifiableList(list);
// 报错:java.lang.UnsupportedOperationException
//list.remove(0);
System.out.println(list);
/**
* jdk9创建只读集合
*/
List<String> list2 = List.of("mysql", "linux", "redis");
list2.remove(0);
System.out.println(list2);
}
}
JDK10
1. var作为局部变量类型推断标识符
public class Main { // var作为局部变量类型推断标识符
public static void main(String[] args) throws Exception {
var strVar = "springboot";
System.out.println(strVar instanceof String);
//根据10L 推断long 类型
var longVar = Long.valueOf(10l);
System.out.println(longVar instanceof Long);
//根据 true推断 boolean 类型
var flag = Boolean.valueOf("true");
System.out.println(flag instanceof Boolean);
// 推断 ArrayList<String>
var listVar = new ArrayList<String>();
System.out.println(listVar instanceof ArrayList);
// 推断 Stream<String>
var streamVar = Stream.of("aa", "bb", "cc");
System.out.println(streamVar instanceof Stream);
if(flag){
System.out.println("这个是 flag 变量,值为true");
}
for (var i = 0; i < 10; i++) {
System.out.println(i);
}
try (var input = new FileInputStream("validation.txt")) {
}
}
}
JDK11
1. httpclinet
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
/**
* 这个功能在JDK9中引入,在JDK10中得到了更新,在JDK11才发布
*/
public class Main { private static final URI uri = URI.create("https://www.cnblogs.com/wlwl/"); public static void main(String[] args) {
testHttp2();
}
/**
* get请求
*/
private static void testGet() {
// 创建连接两种方式: var httpClient = HttpClient.newHttpClient();
var httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofMillis(5000)).build(); // 封装请求参数(默认get请求)
HttpRequest request = HttpRequest.newBuilder().timeout(Duration.ofMillis(3000))
.header("key1", "v1")
.uri(uri).build();
try {
var response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* post请求
*/
private static void testPost() {
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(uri)
.POST(HttpRequest.BodyPublishers.ofString("phone=13113777337&pwd=1234567890"))
// from表单要用下面格式发送
//.header("Content-Type", "application/json")
//.POST(HttpRequest.BodyPublishers.ofString("{\"phone\":\"13113777337\",\"pwd\":\"1234567890\"}"))
.build(); try {
var response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 异步GET请求
*/
private static void testAsynGet() {
var httpClient = HttpClient.newBuilder().build();
var request =
HttpRequest.newBuilder().timeout(Duration.ofMillis(3000))
.header("key1", "v1")
.uri(uri).build();
try {
// 异步请求通过CompletableFuture实现
CompletableFuture<String> result = httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body);
System.out.println(result.get());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发送http2请求
* HTTP2协议的强制要求https,如果目标URI是HTTP的,则无法使用HTTP 2协议
*/
private static void testHttp2() {
var httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofMillis(3000))
.version(HttpClient.Version.HTTP_2)
.build();
var request = HttpRequest.newBuilder().timeout(Duration.ofMillis(3000))
.header("key1", "v1")
.uri(uri)
.build();
try {
var response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
System.out.println(response.version());
} catch (Exception e) {
e.printStackTrace();
}
}
}
JDK13
1. switch
public class Main {
public static void main(String[] args) {
testOldSwitch1();
}
/**
* 旧:没有break,则匹配的case后⾯面会⼀一直输出
*/
public static void testOldSwitch1(){
int i = 1;
switch(i){
case 0:
System.out.println("zero");
//break;
case 1:
System.out.println("one");
//break;
case 2:
System.out.println("two");
//break;
default:
System.out.println("default");
}
} /**
* 新:使用箭头函数,不用声明break,会自动终止,支持多个值匹配,使用逗号分隔
*/
public void testNewSwitch(int i){
switch(i){
case 0 -> {
System.out.println("zero");
System.out.println("这是多⾏行行语句句");
}
case 1,11,111 -> System.out.println("one");
case 2 -> System.out.println("two");
default -> System.out.println("default");
}
}
}
2. 多行文本块
public class Main { public static void main(String[] args) {
/**
* 旧:在java代码里面编写多行源码带有特殊字符则需要转义,如HTML,sql等
*/
String html = "<html>\n" +
"<body>\n" +
"<p>Hello, world</p>\n" +
"</body>\n" +
"</html>\n";
String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +
"WHERE `CITY` = 'INDIANAPOLIS'\n" +
"ORDER BY `EMP_ID`, `LAST_NAME`;\n"; /**
* 新:不用对转义字符进行转义
*/
String html2 = """"
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
}
}
JDK8~13新特性概览的更多相关文章
- Java学习:JDK8的新特性
Java学习:JDK8的新特性 一.十大特性 Lambda表达式 Stream函数式操作流元素集合 接口新增:默认方法与静态方法 方法引用,与Lambda表达式联合使用 引入重复注解 类型注解 最新的 ...
- jdk 9 10 11 12 13 新特性
jdk 9 新特性 1.集合加强 jdk9 为所有集合(List/Set/Map)都增加了 of 和 copyOf 方法,用来创建不可变集合,即一旦创建就无法再执行添加.删除.替换.排序等操作,否则将 ...
- java 28 - 7 JDK8的新特性 之 接口可以使用方法
JDK8的新特性: http://bbs.itcast.cn/thread-24398-1-1.html 其中之一:接口可以使用方法 interface Inter { //抽象方法 public a ...
- 你不知道的JavaScript--Item24 ES6新特性概览
ES6新特性概览 本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用. ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代 ...
- C# 8.0 的新特性概览和讲解
本文转自 https://blog.csdn.net/hez2010/article/details/84036742 C# 8.0 的新特性概览和讲解 前言 新的改变 可空引用类型(Nullable ...
- JDK8.0新特性
连接转载地址:http://www.2cto.com/kf/201609/544044.html Eclipse: http://aiyiupload.oss-cn-beijing.aliyuncs. ...
- jdk8的新特性 Lambda表达式
很多同学一开始接触Java8可能对Java8 Lambda表达式有点陌生. //这是一个普通的集合 List<Employee> list = em.selectEmployeeByLog ...
- JDK8的新特性——Lambda表达式
JDK8已经发布快4年的时间了,现在来谈它的新特性显得略微的有点“不合时宜”.尽管JDK8已不再“新”,但它的重要特性之一——Lambda表达式依然是不被大部分开发者所熟练运用,甚至不被开发者所熟知. ...
- 并发设计模式和锁优化以及jdk8并发新特性
1 设计模式 (1) 单例模式 保证一个类只能一个对象实现.正常的单例模式分为懒汉式和饿汉式,饿汉式就是把单例声明称static a=new A(),系统第一次调用的时候生成(包括调用该类的其他静态资 ...
随机推荐
- 2018-2019-2 20165215《网络对抗技术》Exp8 Web基础
目录 实验内容 基础问题回答 实验步骤 (一)Web前端HTML (二) Web前端javascipt (三)Web后端:MySQL基础:正常安装.启动MySQL,建库.创建用户.修改密码.建表 (四 ...
- 浅析SPDY
1.什么是SPDY? 简单地说,在SSL层上增加一个SPDY会话层,以在一个TCP连接支持并发的HTTP请求.也就是他能通过复用仅仅一条(或几条)TCP连接,在客户端与服务器间发送几十个请求或回应. ...
- MapInfo 文件解析
在MapInfo 中所指的表是单纯的数据表或是图形与数据的结合.一个典型的MapInfo表将主要由*.tab.*.dat.*.wks.*.dbf. *.xls.*.map.*.id.*.ind文件格式 ...
- java实现几种常用排序:选择排序
一.选择排序介绍 选择排序,顾名思义就是用逐个选择的方式来进行排序,逐个选择出数组中的最大(或最小)的元素,直到选择至最后一个元素.此时数组完成了排序. 二.选择排序原理分析 三.选择排序代码实现 / ...
- DP&图论 DAY 5 上午
DP&图论 DAY 5 上午 POJ 1125 Stockbroker Grapevine 有 N 个股票经济人可以互相传递消息,他们之间存在一些单向的通信路径.现在有一个消息要由某个人开 ...
- 从浏览器地址栏输入url到显示页面的步骤
在浏览器地址栏输入URL 浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤 HTTP1.0提供Expires,值为一个绝对时间表示缓存新鲜日期 HTTP1.1增加了Cache-Cont ...
- Java快排
package quickSort; /** * 快速排序 * @author root * */ public class QuickSort { static int[] data = {0,2, ...
- SQL学习(五)多表关联-join
在实际工作中会用到多表联查,此时需要用到关键字JOIN 一.inner join(内连接) 至少有一个匹配时返回行,只返回两个表中连接字段相等的行 如: select * from ticket in ...
- java:Linux(简单命令,远程ssh使用hostname访问,.免密钥登录配置)
1.临时关闭防火墙: service iptables stop 临时开启防火墙: service iptables start 查看防火墙状态: service iptables sta ...
- UOJ#495晒被子
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #inc ...