美文网首页
JDK8新特性(一)

JDK8新特性(一)

作者: 家hao | 来源:发表于2020-11-23 18:35 被阅读0次

    一、JDK8之default关键字

    • 默认方法: 接口里面定义一个默认方法,这个接口的实现类实现了这个接口之后,不用管这个default修饰的方法就可以直接调用,即接口方法的默认实现,(接口名.静态方法)来访问接口中的静态方法。
    public interface Animal {
        void run();
        void eat();
        default void breath(){
            System.out.println("使用氧气呼吸");
        }
        static void test(){
            System.out.println("这是静态方法");
        }
    }
    

    二、JDK8之新增base64加解密API

    • 什么是Base64编码:Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法 基于64个字符A-Z,a-z,0-9,+,/的编码方式,是一种能将任意二进制数据用64种字元组合成字符串的方法,而这个二进制数据和字符串资料之间是可以互相转换的,在实际应上Base64除了能将二进制数据可视化之外,也常用来表示字串加密过后的内容。

    • 使用JDK里sun.misc套件下的BASE64Encoder和BASE64Decoder这两个类

    • 缺点:编码和解码的效率比较差,公开信息说以后的版本会取消这个方法

    • Apache Commons Codec有提供Base64的编码与解码,缺点:需要引用Apache Commons Codec

    public class test {
    
        @Test
        public void test() throws IOException {
            BASE64Encoder encoder = new BASE64Encoder();
            BASE64Decoder decoder = new BASE64Decoder();
            String text = "旧版编解码";
            byte[] textByte = text.getBytes("UTF-8");
            //编码
            String encodedText = encoder.encode(textByte);
            System.out.println(encodedText);
            //解码
            System.out.println(new String(decoder.decodeBuffer(encodedText),"UTF-8"));
        }
    }
    
    • Jdk1.8的java.util包中,新增了Base64的类
    • 好处:不用引包,编解码销量量远大于 sun.misc 和 Apache Commons Codec
    public class test {
    
        @Test
        public void test() throws IOException {
            Base64.Decoder decoder = Base64.getDecoder();
            Base64.Encoder encoder = Base64.getEncoder();
            String text = "JDK8之新编解码";
            byte[] textByte = text.getBytes("UTF-8");
            //编码
            String encodedText = encoder.encodeToString(textByte);
            System.out.println(encodedText);
            //解码
            System.out.println(new String(decoder.decode(encodedText), "UTF-8"));
        }
    }
    

    三、JDK8之时间日期处理类

    • 时间处理再熟悉不过,SimpleDateFormat,Calendar等类
    • 旧版缺点: java.util.Date 是⾮非线程安全的 API设计比较差,日期/时间对象比较,加减麻烦
    • Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理
      1. 新增了很多常见的api,如日期/时间的比较,加减,格式化等
      2. 包所在位置 java.time
      3. 核心类

      LocalDate:不包含具体时间的日期。
      LocalTime:不含日期的时间。
      LocalDateTime:包含了日期及时间。

      1. 处理时间的API
      • JDK8之前:SimpleDateFormat来进行格式化,但SimpleDateFormat并不是线程安全的
      • JDK8之后:引入线程安全的日期与时间DateTimeFormatter
      1. 计算日期时间差 java.time.Duration
    import org.junit.Test;
    import java.time.*;
    import java.time.format.DateTimeFormatter;
    
    public class test {
    
        @Test
        public void test() {
            LocalDate today = LocalDate.now();
            System.out.println(today);
            //获取年月日
            System.out.println(today.getYear());
            System.out.println(today.getMonth());
            System.out.println(today.getDayOfMonth());
            System.out.println(today.getDayOfWeek());
            //加减年份,加厚返回的对象才是修改后的,旧的依旧是旧的
            LocalDate changeDate = today.plusYears(1);
            System.out.println(changeDate.getYear());
            System.out.println(today.getYear());
            //日期比较
            //是否在之前
            System.out.println("isbefore:"+today.isBefore(changeDate));
            //是否在之后
            System.out.println("isbefore:"+today.isAfter(changeDate));
    
            // jdk8引入 DateTimeFormatter是线程安全的SimpleDateFormat
            LocalDateTime lt = LocalDateTime.now();
            System.out.println(lt);// 2019-11-07T23:12:29.056
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String ldtStr = dtf.format(lt);
            System.out.println(ldtStr);// 2019-11-07 23:12:29
    
            //获取指定时间对象
            LocalDateTime ldt = LocalDateTime.of(2020,10,1,10,40,30);
            System.out.println(changeDate);// 2020-10-01T10:40:30
    
            //Duration基于时间值,Period基于日期值,
            //Duration类表示秒或纳秒时间间隔
            //适合处理较短的时间,需要更高的精确性。使用between()方法比较两个瞬间的差:
            Instant start = Instant.parse("2019-11-16T11:15:30.00Z");
            Instant end = Instant.parse("2019-11-16T11:16:30.00Z");
            Duration duration = Duration.between(start,end);//第⼆个参数减第⼀个参数
            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());//两个时间差的纳秒数
    
            //Period 类表示一段时间的年、月、日,使用between()方法获取两个日期之间的差
            LocalDate startDate = LocalDate.of(2019, 11, 16);
            LocalDate endDate = LocalDate.of(2020, 1, 1);
            Period period = Period.between(startDate,endDate);
            System.out.println("per:"+period.getYears());//两个时间差的年数
            System.out.println("per:"+period.getMonths());//两个时间差的月
        }
    }
    

    四、JDK8之Optional类

    • Optional 类用处是什么
      1. 主要解决的问题是空指针异常(NullPointerException)
      2. 本质是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空
    • 创建Optional类
    • of()
      null 值作为参数传递进去,则会抛异常
    Optional<Student> opt = Optional.of(student);
    
    • ofNullable()
      如果对象即可能是 null 也可能是非 null,应该使用 ofNullable() 方法
    Optional<Student> opt = Optional.ofNullable(student);
    
    • get() 方法
      如果值存在则isPresent()方法会返回true,调⽤用get()方法会返回该对象⼀一般使用get之前需要先验证是否有值,不然还会报错
    public class Student {
        private int age;
        public int getAge() {return age; }
        public void setAge(int age) {this.age = age;}
    }
    
    import java.util.Optional;
    
    public class test {
    
        @Test
        public void test(){
            Student student = new Student();
            Optional<Student> opt = Optional.ofNullable(student);
            if(opt.isPresent()){
                System.out.println("optional不为空");
                Student s = opt.get();
            }else {
                System.out.println("optional为空");
            }
        }
    
    • 兜底 orElse方法
      orElse()如果有值则返回该值,否则返回传递给它的参数值
    @Test
    public void test(){
        Student student = null;
        int result = Optional.ofNullable(student).map(obj->obj.getAge()).orElse(4);
        System.out.println(result);
    }
    

    五、JDK8之 lambda表达式

    • 在JDK8之前,Java是不支持函数式编程的,所谓的函数编程,即可理解是将一个函数(也称为“行为”)作为一个参数进行传递, 面向对象编程是对数据的抽象(各种各样的POJO类),而函数式编程则是对行为的抽象(将行为作为一个参数进行传递)
    • 对比创建线程
    //JDK8之前创建线程
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("jdk8之前创建线程");
        }
    });
    
    //jdk8之后Lambda表达式则只需要使用一句话
    new Thread(() -> System.out.println("jdk8之后创建线程"));
    
    • 集合容器里面的字符串排序
    //jdk8之前
    List<String> list =Arrays.asList("aaa","ggg","ffff","ccc");
    Collections.sort(list, new Comparator<String>() {
        @Override
        public int compare(String a, String b) {
            return b.compareTo(a);
        }
    });
    for (String string : list) {
        System.out.println(string);
    }
    
    //jdk8之后
    List<String> list =Arrays.asList("aaa","ggg","ffff","ccc");
    Collections.sort(list, (a,b)->b.compareTo(a));
    for (String string : list) {
        System.out.println(string);
    }
    
    • lambda表达式 使用场景(前提):一个接口中只包含一个方法,则可以使用Lambda表达式,这样的接口称之为“函数接口” 语法: (params) -> expression
    1. 第一部分为括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数;第二部分为一个箭头符号:->;第三部分为方法体,可以是表达式和代码块
    2. 参数列列表 :
      括号中参数列列表的数据类型可以省略不写
      括号中的参数只有一个,那么参数类型和()都可以省略不写
    3. 方法体:
      如果{}中的代码只有一行,无论有返回值,可以省略{},return,分号,要一起省略,其他则需要加上
    • 好处: Lambda 表达式的实现方式在本质是以匿名内部类的方式进行实现

    重构现有臃肿代码,更高的开发效率,尤其是集合Collection操作的时候

    相关文章

      网友评论

          本文标题:JDK8新特性(一)

          本文链接:https://www.haomeiwen.com/subject/nsdviktx.html