【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
    Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
    【10月更文挑战第17天】Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
    77 2
    |
    2月前
    |
    存储 Java
    深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
    【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
    44 3
    |
    7天前
    |
    存储 Java 开发者
    什么是java的Compact Strings特性,什么情况下使用
    Java 9引入了紧凑字符串特性,优化了字符串的内存使用。它通过将字符串从UTF-16字符数组改为字节数组存储,根据内容选择更节省内存的编码方式,通常能节省10%至15%的内存。
    |
    13天前
    |
    容器
    jdk8新特性-详情查看文档
    jdk8新特性-详情查看文档
    33 7
    |
    16天前
    |
    存储 Java 数据挖掘
    Java 8 新特性之 Stream API:函数式编程风格的数据处理范式
    Java 8 引入的 Stream API 提供了一种新的数据处理方式,支持函数式编程风格,能够高效、简洁地处理集合数据,实现过滤、映射、聚合等操作。
    33 5
    |
    19天前
    |
    Oracle 安全 Java
    深入理解Java生态:JDK与JVM的区分与协作
    Java作为一种广泛使用的编程语言,其生态中有两个核心组件:JDK(Java Development Kit)和JVM(Java Virtual Machine)。本文将深入探讨这两个组件的区别、联系以及它们在Java开发和运行中的作用。
    39 1
    |
    27天前
    |
    IDE Java 编译器
    开发 Java 程序一定要安装 JDK 吗
    开发Java程序通常需要安装JDK(Java Development Kit),因为它包含了编译、运行和调试Java程序所需的各种工具和环境。不过,某些集成开发环境(IDE)可能内置了JDK,或可使用在线Java编辑器,无需单独安装。
    61 1
    |
    1月前
    |
    分布式计算 Java API
    Java 8引入了流处理和函数式编程两大新特性
    Java 8引入了流处理和函数式编程两大新特性。流处理提供了一种声明式的数据处理方式,使代码更简洁易读;函数式编程通过Lambda表达式和函数式接口,简化了代码书写,提高了灵活性。此外,Java 8还引入了Optional类、新的日期时间API等,进一步增强了编程能力。这些新特性使开发者能够编写更高效、更清晰的代码。
    32 4
    |
    2月前
    |
    存储 Java API
    优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
    【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
    91 3
    |
    2月前
    |
    设计模式 Java API
    [Java]静态代理与动态代理(基于JDK1.8)
    本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
    31 0
    [Java]静态代理与动态代理(基于JDK1.8)