【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


    相关文章
    |
    2月前
    |
    Java API 数据处理
    Java新特性:使用Stream API重构你的数据处理
    Java新特性:使用Stream API重构你的数据处理
    Java API 开发者
    101 0
    |
    3月前
    |
    安全 Oracle Java
    JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
    JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
    312 0
    JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
    |
    4月前
    |
    Oracle Java 关系型数据库
    新手必看:Java 开发环境搭建之 JDK 与 Maven
    本文分享了 Java 学习中 JDK 安装配置与 Maven 使用的入门知识,涵盖 JDK 下载安装、环境变量设置、Maven 安装配置及本地仓库与镜像设置,帮助新手快速搭建 Java 开发环境。
    476 0
    |
    4月前
    |
    并行计算 Java API
    Java List 集合结合 Java 17 新特性与现代开发实践的深度解析及实战指南 Java List 集合
    本文深入解析Java 17中List集合的现代用法,结合函数式编程、Stream API、密封类、模式匹配等新特性,通过实操案例讲解数据处理、并行计算、响应式编程等场景下的高级应用,帮助开发者提升集合操作效率与代码质量。
    223 1
    |
    4月前
    |
    安全 Java 微服务
    Java 最新技术和框架实操:涵盖 JDK 21 新特性与 Spring Security 6.x 安全框架搭建
    本文系统整理了Java最新技术与主流框架实操内容,涵盖Java 17+新特性(如模式匹配、文本块、记录类)、Spring Boot 3微服务开发、响应式编程(WebFlux)、容器化部署(Docker+K8s)、测试与CI/CD实践,附完整代码示例和学习资源推荐,助你构建现代Java全栈开发能力。
    543 1
    |
    4月前
    |
    缓存 安全 Java
    Java 并发新特性实战教程之核心特性详解与项目实战
    本教程深入解析Java 8至Java 19并发编程新特性,涵盖CompletableFuture异步编程、StampedLock读写锁、Flow API响应式流、VarHandle内存访问及结构化并发等核心技术。结合电商订单处理、缓存系统、实时数据流、高性能计数器与用户资料聚合等实战案例,帮助开发者高效构建高并发、低延迟、易维护的Java应用。适合中高级Java开发者提升并发编程能力。
    141 0
    |
    4月前
    |
    安全 Java API
    Java 17 及以上版本核心特性在现代开发实践中的深度应用与高效实践方法 Java 开发实践
    本项目以“学生成绩管理系统”为例,深入实践Java 17+核心特性与现代开发技术。采用Spring Boot 3.1、WebFlux、R2DBC等构建响应式应用,结合Record类、模式匹配、Stream优化等新特性提升代码质量。涵盖容器化部署(Docker)、自动化测试、性能优化及安全加固,全面展示Java最新技术在实际项目中的应用,助力开发者掌握现代化Java开发方法。
    217 1
    |
    4月前
    |
    IDE Java API
    Java 17 新特性与微服务开发的实操指南
    本内容涵盖Java 11至Java 17最新特性实战,包括var关键字、字符串增强、模块化系统、Stream API、异步编程、密封类等,并提供图书管理系统实战项目,帮助开发者掌握现代Java开发技巧与工具。
    267 1
    |
    4月前
    |
    Java 数据库连接 API
    Java 8 + 特性及 Spring Boot 与 Hibernate 等最新技术的实操内容详解
    本内容涵盖Java 8+核心语法、Spring Boot与Hibernate实操,按考试考点分类整理,含技术详解与代码示例,助力掌握最新Java技术与应用。
    155 2