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新特性概览的更多相关文章

  1. Java学习:JDK8的新特性

    Java学习:JDK8的新特性 一.十大特性 Lambda表达式 Stream函数式操作流元素集合 接口新增:默认方法与静态方法 方法引用,与Lambda表达式联合使用 引入重复注解 类型注解 最新的 ...

  2. jdk 9 10 11 12 13 新特性

    jdk 9 新特性 1.集合加强 jdk9 为所有集合(List/Set/Map)都增加了 of 和 copyOf 方法,用来创建不可变集合,即一旦创建就无法再执行添加.删除.替换.排序等操作,否则将 ...

  3. java 28 - 7 JDK8的新特性 之 接口可以使用方法

    JDK8的新特性: http://bbs.itcast.cn/thread-24398-1-1.html 其中之一:接口可以使用方法 interface Inter { //抽象方法 public a ...

  4. 你不知道的JavaScript--Item24 ES6新特性概览

    ES6新特性概览 本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用. ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代 ...

  5. C# 8.0 的新特性概览和讲解

    本文转自 https://blog.csdn.net/hez2010/article/details/84036742 C# 8.0 的新特性概览和讲解 前言 新的改变 可空引用类型(Nullable ...

  6. JDK8.0新特性

    连接转载地址:http://www.2cto.com/kf/201609/544044.html Eclipse: http://aiyiupload.oss-cn-beijing.aliyuncs. ...

  7. jdk8的新特性 Lambda表达式

    很多同学一开始接触Java8可能对Java8 Lambda表达式有点陌生. //这是一个普通的集合 List<Employee> list = em.selectEmployeeByLog ...

  8. JDK8的新特性——Lambda表达式

    JDK8已经发布快4年的时间了,现在来谈它的新特性显得略微的有点“不合时宜”.尽管JDK8已不再“新”,但它的重要特性之一——Lambda表达式依然是不被大部分开发者所熟练运用,甚至不被开发者所熟知. ...

  9. 并发设计模式和锁优化以及jdk8并发新特性

    1 设计模式 (1) 单例模式 保证一个类只能一个对象实现.正常的单例模式分为懒汉式和饿汉式,饿汉式就是把单例声明称static a=new A(),系统第一次调用的时候生成(包括调用该类的其他静态资 ...

随机推荐

  1. isEmpty和isBlank区别

    isEmpty 判断某字符串是否为空,为空的标准是 str==null或 str.length()==0 StringUtils.isEmpty(null) = true StringUtils.is ...

  2. Monkeyrunner 使用说明

    monkeyrunner为android系统新公开的一个测试工具.有助于开发人员通过脚本部署较大规模的自动化测试. Monkeyrunner       本文档中包含 一个简单的monkeyrunne ...

  3. (“(null)” is of a model that is not supported by this version of Xcode. Please...)

    真机测试遇到以下问题: (还以为手机不支持Xcode的版本呢) 解决方法: 发现只要将XCode重启后就可以真机运行了,碰见这个问题的朋友可以试下,我反正是被坑了半小时...

  4. BOM Summary P268-P269

    The Browser Object Model(BOM) is based on the window object, which represents the browser window and ...

  5. I'm using Python 2.7.2 ImportError No module named bz2

    安装mongodb的时候 提示错误 这是因为同时装了python2.6和2.7的缘故 sudo cp /usr/lib64/python2.6/lib-dynload/bz2.so /usr/loca ...

  6. SQL常见面试题(借书卡表_图书表_借书记录表)

    问题描述: 本题用到下面三个关系表: CARD 借书卡:          CNO 卡号,NAME 姓名,CLASS 班级 BOOKS 图书:           BNO 书号,BNAME 书名,AU ...

  7. 【HANA系列】SAP HANA SQL计算某日期是当月的第几天

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL计算某日 ...

  8. 【HANA系列】SAP HANA SQL计算某日期是当年的第几天

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL计算某日 ...

  9. 【HANA系列】SAP HANA SQL条件判断是NULL的写法

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL条件判断 ...

  10. 【HANA系列】SAP HANA SQL字符串连接操作

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL字符串连 ...