• Java8新特性(三)——Optional类、接口方法与新时间日期API


    一、Optional容器类

      这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。  

      查看结构图可以看到有如下常用方法:

        of(T)——创建一个非空的Optional实例(使用empty创建一个空的Optional实例)

        ofNullable(T)——若参数不为Null,则创建一个非空实例,否则创建一个空实例

        isPresent——是否存在值(存在返回true,否则返回false)

        orElse(T)——有值则将其返回,否则返回参数中的指定值

        get——有值则返回,否则抛出异常

        orElseGet(Supplier)——与orElse类似,但他可以接收Supplier接口返回的值

        map(Function)——有值则对其进行Function处理返回处理后的Optional(实际上之前两节已经接触过)

        flatMap——与map类似,但是返回值必须是Optional

      看实例:

     @Test
        public void test1() {
            // of()——获取Optional实例
            Optional<Employee> op = Optional.of(new Employee("张三", 10, Status.VOCATION));
            // get()——获取Optional中的实例
            System.out.println(op.get());
            // empty()——构建空的Optional实例
            Optional<Object> op2 = Optional.empty();
            // ofNullable()——若参数非空构建实例,否则构建空实例(允许构建空实例)
            Optional<Employee> op3 = Optional.ofNullable(null);
            if (op3.isPresent()) { // isPresent()——是否存在值
                System.out.println(op3.get());
            } else {
                System.out.println("实例为空!");
            }
            // orElse()——有值则获取,否则返回指定参数的值
            Employee employee = op3.orElse(new Employee("李四", 11, Status.FREE));
            System.out.println(employee);
            // orElseGet()——可以接收供给型接口返回的值
            Employee employee1 = op3.orElseGet(() -> new Employee("王五", 12, Status.FREE));
            System.out.println("employee1 = " + employee1);
            // map()——Stream中已经用过,返回处理后的值
            Optional<String> optional = op.map(Employee::getName);
            System.out.println(optional.get());
        }

      实际使用中可以对可能为空的进行封装使用:

    // 注意不能初始化为Null
    private Optional<Employee> emp = Optional.empty();

    二、接口中的默认方法与静态方法

      静态方法

      1.定义接口,提供默认实现,则子类可以直接使用:

    public interface MyFun {
        // 使用default修饰
        default String getName() {
            return "MyFun:name";
        }
    }
    public class MySubClass implements MyFun{
        public static void main(String[] args) {
            MySubClass subClass = new MySubClass();
            String name = subClass.getName();
            System.out.println(name);// MyFun:name
        }
    }

      2.若继承的类与接口有相同方法,则采取类优先

    public class MyClass {
    
        public String getName() {
            return "MyClass:name";
        }
    }
    public class MySubClass extends MyClass implements MyFun{
        public static void main(String[] args) {
            MySubClass subClass = new MySubClass();
            String name = subClass.getName();
            System.out.println(name);// MyClass:name
        }
    }

      3.若实现了多个接口具有相同默认方法,则必须指定实现的接口的类

    return MyFun.super.getName()

      静态方法

      // 接口中的静态方法
        static void show() {
            System.out.println("MyFun.static.show");
        }
    public static void main(String[] args) {
            MyFun.show();
        }

     三、全新的时间日期API

      Java8之前的时间日期类用法,可以参见之前随笔http://www.cnblogs.com/jiangbei/p/6905832.html

      全新的Java8的时间日期API更多介绍可以参见ImportNew的文章:http://www.importnew.com/14857.html

      常见示例,请参见:http://blog.csdn.net/chenleixing/article/details/44408875

      全新的时间日期API移植到了规范的java.time包下(而不是原来的SimpleDateFormat还在java.text包下)

      本地时间日期与时间戳

      LocalDate、LocalTime、LocalDateTime——标准的ISO-8601标准,并且是线程安全的不可变对象!

      本地时间代码示例:

    public static void main(String[] args) {
            // LocalDate LocalTime LocalDateTime用法都是类似的
            // now()——获取当前系统时间
            LocalDateTime dateTime = LocalDateTime.now();
            System.out.println("dateTime = " + dateTime); // dateTime = 2017-09-26T18:05:12.990
            LocalDate date = LocalDate.now();
            System.out.println("date = " + date); // date = 2017-09-26
            // of()——根据指定时间参数返回对象
            LocalDateTime of = LocalDateTime.of(2017, 10, 1, 10, 59);
            System.out.println("of = " + of); // of = 2017-10-01T10:59
            LocalTime of1 = LocalTime.of(21, 58, 3);
            System.out.println("of1 = " + of1);// of1 = 21:58:03
            // plus系列的时间偏移加,minus系列减
            LocalDateTime dateTime1 = dateTime.plusYears(3);
            System.out.println("dateTime1 = " + dateTime1); // dateTime1 = 2020-09-26T18:12:20.622
            LocalTime of2 = of1.minusHours(2);
            System.out.println("of2 = " + of2); // of2 = 19:58:03
            // get系列获取时间日期字段
            System.out.println(dateTime1.getYear()); // 2020
            System.out.println(dateTime1.getDayOfWeek());// SATURDAY
            // 更多未演示方法,请参见API
        }

      未完方法请参见下表或者API查看完整方法:

    now() 静态方法,根据当前时间创建对象 LocalDate localDate = LocalDate.now();
    LocalTime localTime = LocalTime.now();
    LocalDateTime localDateTime = LocalDateTime.now();
    of() 静态方法,根据指定日期/时间创建
    对象
    LocalDate localDate = LocalDate.of(2016, 10, 26);
    LocalTime localTime = LocalTime.of(02, 22, 56);
    LocalDateTime localDateTime = LocalDateTime.of(2016, 10,
    26, 12, 10, 55);
    plusDays, plusWeeks,
    plusMonths, plusYears
    向当前 LocalDate 对象添加几天、
    几周、几个月、几年
    minusDays, minusWeeks,
    minusMonths, minusYears
    从当前 LocalDate 对象减去几天、
    几周、几个月、几年
    plus, minus 添加或减少一个 Duration 或 Period
    withDayOfMonth,
    withDayOfYear,
    withMonth,
    withYear
    将月份天数、年份天数、月份、年
    份 修 改 为 指 定 的 值 并 返 回 新 的
    LocalDate 对象
    getDayOfMonth 获得月份天数(1-31)
    getDayOfYear 获得年份天数(1-366)
    getDayOfWeek 获得星期几(返回一个 DayOfWeek
    枚举值)
    getMonth 获得月份, 返回一个 Month 枚举值
    getMonthValue 获得月份(1-12)
    getYear 获得年份
    until 获得两个日期之间的 Period 对象,
    或者指定 ChronoUnits 的数字
    isBefore, isAfter 比较两个 LocalDate
    isLeapYear 判断是否是闰年
    View Code

      Instant 时间戳

      用于“时间戳”的运算。它是以Unix元年(传统 的设定为UTC时区1970年1月1日午夜时分)开始 所经历的描述进行运算

       @Test
        public void test1() {
            // now()——获取的是UTC时区的当前时间
            Instant now = Instant.now();
            System.out.println("now = " + now); // now = 2017-09-26T10:20:18.211Z
            // toEpochMilli()——对应的毫秒数
            long epochMilli = now.toEpochMilli();
            System.out.println("epochMilli = " + epochMilli); // epochMilli = 1506427725628
            // 时间偏移,相对Unix元年的时间差
            Instant instant = Instant.ofEpochSecond(1);
            System.out.println("instant = " + instant);
            // Duration()——计算时间之间间隔;Period()——计算两个日期间隔(本地日期之间的间隔,同样有Duration类似的操作)
            //             不局限于时间戳,对于前面提到的本地日期同样适用
            Instant now1 = Instant.now();
            Instant now2 = Instant.now();
            Duration duration = Duration.between(now1, now2);
            // Duration.get系列——获取时间间隔;to系列获取毫秒
            duration.getSeconds();
            duration.toMillis();
        }

      日期校正器

       TemporalAdjuster : 时间校正器。有时我们可能需要获 取例如:将日期调整到“下个周日”等操作。

        TemporalAdjusters : 该类通过静态方法提供了大量的常 用 TemporalAdjuster 的实现。

      @Test
        public void test2() {
            LocalDateTime now = LocalDateTime.now();
            // 通过with系列的操作,也可以进行日期的调整
            LocalDateTime now1 = now.withDayOfMonth(16);
            System.out.println("now1 = " + now1); // now1 = 2017-09-16T20:25:47.475
            // 通过时间校正器指定特定的校正
            now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));// 下一个周日
            // 当然,除了通过工具类,还可以通过实现接口完成自定义的日期校正(Lambda表达式)
        }

      java.time.format.DateTimeFormatter 类:该类提供了三种 格式化方法:

        预定义的标准格式  语言环境相关的格式  自定义的格式

      @Test
        public void test3() {
            // 定义格式化的标准
            DateTimeFormatter dtf1 = DateTimeFormatter.ISO_DATE_TIME;
            DateTimeFormatter dtf2 = DateTimeFormatter.ISO_DATE;
    
            LocalDateTime now = LocalDateTime.now();
            // 通过指定格式化器进行格式化
            String format = now.format(dtf1);
            System.out.println("format = " + format); // format = 2017-09-26T20:41:23.665
            String format1 = now.format(dtf2);
            System.out.println("format1 = " + format1); //format1 = 2017-09-26
    
            // 自定义格式化器
            DateTimeFormatter myDtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
            String format2 = now.format(myDtf);
            System.out.println("format2 = " + format2); // format2 = 2017/09/26
            // 解析字符串为日期(请注意月份日期位数必须为2位!)
            String str = "2017/10/01";
            LocalDate parse = LocalDate.parse(str, myDtf);
            System.out.println("parse = " + parse); // parse = 2017-10-01
    
        }

      时区的操作,与传统时间的转换;这里暂不展开:ZonedDate、ZonedTime、ZonedDateTime

       重复注解与类型注解,也暂不展开...

  • 相关阅读:
    实验综合-2021.1.31
    利用文件上传漏洞远程控制服务器
    [转载]文件上传漏洞
    第五周学习视频(二)
    第五周学习视频(一)
    第四周——上课笔记(二)
    第四周——上课笔记(一)
    第四周学习视频(一)
    mooc视频笔记(哈工大)第4讲-关系模型之关系代数
    第三周学习视频(二)
  • 原文地址:https://www.cnblogs.com/jiangbei/p/7595743.html
Copyright © 2020-2023  润新知