JDK8~13新特性概览

时间:2019-11-14
本文章向大家介绍JDK8~13新特性概览,主要包括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("私有方法");
    };
}
View Code

 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"));//圣魔导师
    }
}
View Code

 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());//两个时间差的纳秒数
    }
}
View Code

 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();
    }
}
View Code

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;
    }
}
View Code

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);
View Code

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();
        }
    }
}
View Code

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);
    }
}
View Code

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);
    }
}
View Code

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")) {
        }
    }
}
View Code 

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();
        }
    }
}
View Code

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");
        }
    }
}
View Code

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`;
                       """;
    }
}
View Code

						

原文地址:https://www.cnblogs.com/wlwl/p/11815824.html