【Java系列】JDK1.8新特性

简介: Java8(又称为 jdk 1.8) 是 Java 语言开发迄今为止的一个最主要和用户最多的一个版本。Java8是Oracle公司于2014年3月18日发布 ,它不仅支持函数式编程,而且还拥有新的日期 API,Stream API 等操作,下面胖虎带领大家一探究竟Java 8的一些新特性。1.Lambda表达式2.添加默认方法3.Stream操作4.Optional 类5.Java时间APILambda 允许把函数作为一个方法的参数,使用Lambda表达

 目录

1.Lambda表达式

2.添加默认方法

3.Stream操作

4.Optional 类

5.Java时间API


Java8(又称为 jdk 1.8) 是 Java 语言开发迄今为止的一个最主要和用户最多的一个版本。Java8是Oracle公司于2014年3月18日发布 ,它不仅支持函数式编程,而且还拥有新的日期 API,Stream API 等操作。

1.Lambda表达式

Lambda 允许把函数作为一个方法的参数,使用Lambda表达式可以使代码变的更加简洁紧凑、简洁表达。

lambda表达式的重要特征:

    • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值((x1,x2))。
    • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
    • 可选的大括号:如果函数主体包含了一个语句,就不需要使用大括号。
    • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回一个数值。
    • lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义,详细见如下案例)

    lambda表达式的语法:

    (parameters) -> expression
    (parameters) ->{ statements; }
    (x)->{system.out.prinln} //直接打印x参数;

    image.gif

    lambda表达式简单例子:

    /**
     * lambda
     *
     */
    public class Java8TestLambda {
        public static  void main(String [] args){
            CacualtePriceService cacualteAddPriceService=(x1,x2)->(x1+x2);
            CacualtePriceService cacualteSubPriceService=(x1,x2)->(x1-x2)
            System.out.println(cacualteAddPriceService.cacluatePrice(1.2f,2.2f));//3.4
            System.out.println(cacualteSubPriceService.cacluatePrice(3.2f,1.2f));//2.0
            System.out.println("------------------使用策略模式----------------------");
            System.out.println(operate(1.2f,2.2f,(x1,x2)->(x1+x2)));//3.4
            System.out.println(operate(3.2f,1.2f,(x1,x2)->(x1-x2)));//2.0
        }
        /**
         * 计算价格接口
         */
        interface CacualtePriceService{
            Float cacluatePrice(Float x1,Float x3);
        }
        static Float operate(float x1, float x2, CacualtePriceService cacualtePriceService){
           return cacualtePriceService.cacluatePrice(x1,x2);
        }
    }

    image.gif

    打印结果:

    3.4
    2.0
    ------------------使用策略模式----------------------
    3.4
    2.0

    image.gif

    由上面的例子可知,Lambda可以简化函数接口(接口中只有一个方法,例如上述例子中CacualtePriceService接口)的实现方法。

    // static final float num=1.1f;
        public static  void main(String [] args){
            float num=1.1f;
            CacualtePriceService cacualteAddPriceService=(x1,x2)->(x1+x2+num);
            CacualtePriceService cacualteSubPriceService=(x1,x2)->(x1-x2+num);
            num=2;
        }
    console://当修改num=2 时候会报错:
    Error:(14, 70) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量

    image.gif

    当修改num=2 时候会报错:从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量。

    2.添加默认方法

    java 8添加了接口的默认方法,简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现的方法。

    我们只需在方法名前面加个 default 关键字即为默认方法。

    为什么要有这个特性?

    之前的接口,当需要修改接口时候,需要修改全部实现该接口的类,然而,对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。所以引进的默认方法,目的是为了解决接口的修改与现有的实现不兼容的问题

    默认方法案例如下:

    /**
     * jdk 1.8 默认方法
     */
    public class DafaultMethod {
        interface Car {
            static void staticRun() {
                System.out.println("测试汽车静态接口");
            }
            default void defaultRun() {
                System.out.println("测试汽车默认接口");
            }
            void run();
        }
        static class QicheCar implements Car {
            @Override
            public void run() {
                System.out.println("测试汽车实现接口");
                defaultRun();
                Car.staticRun();
            }
        }
        public static void main(String[] args) {
            QicheCar car = new QicheCar();
            car.run();
        }
    }

    image.gif

    输出内容:

    测试汽车实现接口
    测试汽车默认接口
    测试汽车静态接口

    image.gif

    由上述案例可知,接口直接可以调用静态方法以及默认方法。

    3.Stream操作

    要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选,排序,聚合等操作。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。Java中的Stream并不会存储元素,而是按需计算。

    数据源中流的来源 可以是集合,数组,I/O channel, 产生器generator 等。

    (1)Stream基本操作

    一、获取流

    1.1 所有的 Collection 集合都可以通过 stream 默认方法获取流

    1.2 Stream 接口的静态方法 of 可以获取数组对应的流。

    二、中间操作

    1.过滤 filter

    2.去重 distinct

    3.排序 sorted

    4.截取 limit

    5.跳跃 skip

    6.转换map/flatMap

    7.其他 peek

    三、终止操作

    1、循环 forEach

    2、计算 min、max、count、 average

    3、匹配 anyMatch、 allMatch、 noneMatch、findFirst、 findAny

    4、汇聚 reduce

    5、收集器 toArray collect

     

    4.Optional 类

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

    5.Java时间API

    Java 8 在 java.time 包下提供了很多新的 API 。两个比较重要的 API:Local(本地) − 简化了日期时间的处理,没有时区的问题。Zoned(时区) − 通过制定的时区处理日期时间。

    具体案例参考如下:

    public void testLocalDateTime(){
            // 获取当前时间
            LocalDateTime ldt = LocalDateTime.now();
            System.out.println(ldt);//2021-06-29T16:27:58.543
            // 获取指定时间
            LocalDateTime ld2 = LocalDateTime.of(2016, 11, 21, 10, 10, 10);
            System.out.println(ld2);//2016-11-21T10:10:10
            // 指定时间后移动2年
            LocalDateTime ldt3 = ld2.plusYears(20);
            System.out.println(ldt3);//2036-11-21T10:10:10
            // 指定时间前移动2月
            LocalDateTime ldt4 = ld2.minusMonths(2);
            System.out.println(ldt4);//2016-09-21T10:10:10
            System.out.println(ldt.getYear());//2021
            System.out.println(ldt.getMonthValue());//6
            System.out.println(ldt.getDayOfMonth());//29
            System.out.println(ldt.getHour());//16
            System.out.println(ldt.getMinute());//27
            System.out.println(ldt.getSecond());//58
            System.out.println("---------------当前时间解析-------------------");
            // 当前时间解析
            LocalDateTime currentTime = LocalDateTime.now();
            System.out.println("当前时间: " + currentTime);//2021-06-29T16:27:58.546
            LocalDate date1 = currentTime.toLocalDate();
            System.out.println("date1: " + date1);// 2021-06-29
            Month month = currentTime.getMonth();
            Integer mon=month.ordinal()+1;
            int day = currentTime.getDayOfMonth();
            int seconds = currentTime.getSecond();
            System.out.println("月: " + month +"/"+mon+", 日: " + day +", 秒: " + seconds);//月: JUNE/6, 日: 29, 秒: 58
            LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
            System.out.println("date2: " + date2);//date2: 2012-06-10T16:27:58.546
            // 12 december 2014
            LocalDate date3 = LocalDate.of(2014, Month.FEBRUARY, 25);
            System.out.println("date3: " + date3);//date3: 2014-02-25
            // 22 小时 15 分钟
            LocalTime date4 = LocalTime.of(22, 15);
            System.out.println("date4: " + date4);//date4: 22:15
            // 解析字符串
            LocalTime date5 = LocalTime.parse("20:15:30");
            System.out.println("date5: " + date5);//date5: 20:15:30
            System.out.println("-------------Instant : 时间戳--------------------");
            // Instant : 时间戳。 (使用 Unix 元年  1970年1月1日 00:00:00 所经历的毫秒值)
            Instant ins = Instant.now();  //默认使用 UTC 时区 比大陆时间提前8小时
            System.out.println("ins"+ins);//ins2021-06-29T08:27:58.578Z
            OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));
            System.out.println("odt"+odt);//odt2021-06-29T16:27:58.578+08:00
            System.out.println("ins.getNano():"+ins.getNano());//ins.getNano():578000000
            Instant ins2 = Instant.ofEpochSecond(5);
            System.out.println("ins2:"+ins2);//ins2:1970-01-01T00:00:05Z
            System.out.println("----------耗费时间统计------------");
            Instant ins1 = Instant.now();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            Instant ins3 = Instant.now();
            System.out.println("所耗费时间为:" + Duration.between(ins1, ins3));//所耗费时间为:PT1.005S
            LocalDate ld3 = LocalDate.now();
            LocalDate ld4 = LocalDate.of(2011, 1, 1);
            Period pe = Period.between(ld4, ld3);
            System.out.println(pe.getYears());//10
            System.out.println(pe.getMonths());//5
            System.out.println(pe.getDays());//28
        }

    image.gif


    相关文章
    |
    22天前
    |
    安全 Java 数据安全/隐私保护
    |
    22天前
    |
    搜索推荐 Java
    Java的面向对象特性主要包括封装、继承和多态
    【4月更文挑战第5天】Java的面向对象特性主要包括封装、继承和多态
    15 3
    |
    1月前
    |
    人工智能 Java 编译器
    Java 19的未来:新特性、性能优化和更多
    Java 19的未来:新特性、性能优化和更多
    |
    1天前
    |
    安全 Java 大数据
    探索Java的奇妙世界:语言特性与实际应用
    探索Java的奇妙世界:语言特性与实际应用
    |
    2天前
    |
    Java
    【Java基础】详解面向对象特性(诸如继承、重载、重写等等)
    【Java基础】详解面向对象特性(诸如继承、重载、重写等等)
    8 0
    |
    8天前
    |
    机器学习/深度学习 Java API
    Java8中的新特性
    Java8中的新特性
    |
    10天前
    |
    Oracle Java 关系型数据库
    Java 开发者必备:JDK 版本详解与选择策略(含安装与验证)
    Oracle Java SE 支持路线图显示,JDK 8(LTS)支持至2030年,非LTS版本如9-11每6个月发布且支持有限。JDK 11(LTS)支持至2032年,而JDK 17及以上版本现在提供免费商用许可。LTS版本提供长达8年的支持,每2年发布一次。Oracle JDK与OpenJDK有多个社区和公司构建版本,如Adoptium、Amazon Corretto和Azul Zulu,它们在许可证、商业支持和更新方面有所不同。个人选择JDK时,可考虑稳定性、LTS、第三方兼容性和提供商支持。
    24 0
    |
    11天前
    |
    分布式计算 Java API
    Java 8新特性之Lambda表达式与Stream API
    【4月更文挑战第16天】本文将介绍Java 8中的两个重要新特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种新的编程语法,它允许我们将函数作为参数传递给其他方法,从而使代码更加简洁、易读。Stream API是Java 8中引入的一种新的数据处理方式,它允许我们以声明式的方式处理数据,从而使代码更加简洁、高效。本文将通过实例代码详细讲解这两个新特性的使用方法和优势。
    |
    17天前
    |
    Java API 开发者
    Java 8新特性之函数式编程实战
    【4月更文挑战第9天】本文将深入探讨Java 8的新特性之一——函数式编程,通过实例演示如何运用Lambda表达式、Stream API等技术,提高代码的简洁性和执行效率。
    |
    18天前
    |
    存储 Java API
    java8新特性 lambda表达式、Stream、Optional
    java8新特性 lambda表达式、Stream、Optional