美文网首页
java8 - java9 新特性 (一)

java8 - java9 新特性 (一)

作者: wangxg_de27 | 来源:发表于2019-10-05 07:54 被阅读0次

    参考传智视频,整理中。。。

    01_课程介绍

    1. 重点讲解java8 和java9当中的新特性
    2. 课程定位:
      适合有一定java编程经验的同学,渴望了解最新java前沿技术的同学,快速入门
    3. 课程内容:
      day01 lambda表达式,函数式接口、接口更新
      day02 方法引用、常用函数式接口
      day03 Stream流式处理api、模块化

    02_Java版本特性更新历史

    版本号 年份/代号 新特性(部分举例)
    1.0 1996年
    1.1 1997年 JDBC
    1.2 1998年 / Playground(运动场) 集合、字符串池
    1.3 2000年 / Kestrel(美洲红隼) JDBC
    1.4 2004年 / Merlin(灰背隼) XML、正则、JDBC3.0、断言、NIO
    5.0 2004年 / Tigger (老虎) 泛型、注解、可变参数、枚举
    6.0 2006年 / Mustang (野马) 脚本、JDBC 4.0
    7.0 2011年 / Dolphin (海豚) NIO2.0 、try-with-resources
    8.0 2014年3月 / Spider (蜘蛛) 接口更新、lambda表达式、方法引用、Stream API、函数式接口、Hashorn、JavaFX、DateTime
    9.0 2017年9月 Jigsaw模块化、Jshell、接口小更新

    Lambda标准格式
    **1.一些参数

    1. 一个箭头
    2. 一些代码**

    如果参数有多个,则使用逗号分隔; 如果没有参数,则留空
    箭头是固定写法
    大括号相当于方法体

    省略规则

    1. 参数的类型可以省略,但是只能同时省略所有参数的类型,或者干脆都不省略,不能致谢个别参数的类型
    2. 如果参数有且仅有一个,那么小括号可以省略
    3. 如果大括号之内的语句有且仅有一个,那么无论有没有返回值,return、大括号和分好,都可以省略

    03_面向对象的Runnable接口写法

     public static void main(String[] args) {
            //匿名内部类对象
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("多线程执行!!!");
                }
            };
            new Thread(runnable).start();
    
            //Lambda表达式使用
            new Thread(() -> System.out.println("111")).start();
        }
    

    day01_04_编程思想转换

    如何进行软件开发

    1. 自己编写二进制
    2. 汇编语言
    3. 面向过程
    4. 面向对象
    5. 函数式编程思想

    面向对象强调“一切皆对象“,如果要想做事情,必须找到对象来做
    函数式编程思想强调”做什么,而不是怎么做“

    05_体验Lambda的更优写法

    public static void main(String[] args){
        new Thread().start(() -> System.out.println("执行了。。。"));
    }
    

    06_复习并分析匿名内部类语法

    Lambda分析

    Runnable接口当中的run方法语义分析

    public void run(){
            //方法体
    }
    
    1. 参数列表为空,不需要任何条件就可以执行该方法
    2. 没有返回值,方法不产生任何数据结果
    3. 方法体大括号,这才是关键的方法内容所在
    () -> System.out.println("线程任务执行”);
    
    1. 小括号,不需要任何参数,即可直接执行
    2. 箭头指向后面要做的事情
    3. 尖肉后面就好比方法体大括号,代表具体要做的内容

    07_Lambda表达式的标准格式

    Lambda表达式的标准格式
    三要素:

    1. 一些参数
    2. 一个箭头
    3. 一些代码

    (参数类型 参数名称) -> { 一些代码}

    1. 如果参数有多个,那么使用逗号分隔,如果参数没有,则留空
    2. 箭头是固定写法
    3. 大括号相当于方法体

    08_练习使用Lambda的标准格式

    1、接口 Cook.java

    /**
     * lambda表达式的必要前提
     *  1. 必须有一个接口
     *  2.接口当中必须保证有且有个抽象方法
     */
    public interface Cook {
        /*
         * 唯一的抽象方法
         */
        void makeFood();
    }
    
    

    2、实现类

    public class CookImpl implements Cook {
        @Override
        public void makeFood() {
            System.out.println("makeFood.......");
        }
    }
    

    3、内部类实现

    public class Demo02_InnerClass {
        public static void main(String[] args) {
            method(new Cook() {
                @Override
                public void makeFood() {
                    System.out.println("makeFood...内部类实现。。。");
                }
            });
        }
        private static void method(Cook cook){
            cook.makeFood();
        }
    }
    
    
    public class Demo02_Lambda {
        public static void main(String[] args) {
           method(() -> System.out.println("makeFood... Lambda实现方式。。。"));
        }
        private static void method(Cook cook){
            cook.makeFood();
        }
    }
    
    

    09_Lambda表达式的参数和返回值

    1、实体类

    public class Person(){
        private String name;
        private int age;
        //setter/getter、 构造方法、toString()省略
    }
    

    2、测试类
    方式一:
    使用匿名内部类排序

    public class SortTest{
        public static void main(String[] args) {
            Person[] arrays = {
                    new Person("刘备", 30),
                    new Person("张飞", 25),
                    new Person("张苞", 3),
                    new Person("关羽", 27),
            };
            System.out.println(Arrays.toString(arrays));
            Arrays.sort(arrays, new Comparator<Person>() {
                @Override
                public int compare(Person o1, Person o2) {
                    return o1.getAge() - o2.getAge();
                }
            });
            System.out.println("-------------------------------------排序后---------------------------------");
            System.out.println(Arrays.toString(arrays));
        }
    

    方式二:
    Lambda方式

    public class Demo02_Lambda {
        public static void main(String[] args) {
            Person[] arrays = {
                    new Person("刘备", 30),
                    new Person("张飞", 25),
                    new Person("张苞", 3),
                    new Person("关羽", 27),
            };
            System.out.println(Arrays.toString(arrays));
            Arrays.sort(arrays,(Person o1, Person o2) -> {
                return o1.getAge() - o2.getAge();
            });
            System.out.println("-------------------------------------排序后---------------------------------");
            System.out.println(Arrays.toString(arrays));
        }
    }
    

    10_练习使用Lambda的参数和返回值

    public interface Calculator {
        //两数求和
        int sum(int a, int b);
    }
    //测试类
    public class CalculatorLambdaTest {
        public static void main(String[] args) {
            method( (a, b) -> { return a + b ;});
        }
        private static void method(Calculator calc){
            int result = calc.sum(1,2);
            System.out.println(result);
        }
    }
    

    11_Lambda表达式的省略格式

    上面的表达式可以再简写

    public class CalculatorLambdaFormat {
        public static void main(String[] args) {
            // 带有参数类型
            //1.method( ( int a,  int b) -> { return a + b ;});
     
            //省略参数类型
            //2.method( ( a,  b) -> { return a + b ;});
    
            //大括号语句有且只有一个,可省略大括号、return、分号
            //3.method( (a , b) -> a + b);
            method( (a , b) -> a + b);
        }
        private static void method(Calculator calc){
            int result = calc.sum(1,2);
            System.out.println(result);
        }
    }
    

    Lambda表达式的省略规则:
    1.参数的类型可以省略,但是只能同时省略所有参数的类型,或者干脆都不省略,不能致谢个别参数的类型
    2.如果参数有且仅有一个,那么小括号可以省略
    3.如果大括号之内的语句有且仅有一个,那么无论有没有返回值,return、大括号和分好,都可以省略

    12_练习使用Lambda的省略格式

    /**
     * lambda表达式的必要前提
     *  1. 必须有一个接口
     *  2.接口当中必须保证有且有个抽象方法
     */
    public interface Cook {
        void makeFood();
    }
    //测试类
    public class Demo01_Lambda {
        public static void main(String[] args) {
            method( () -> System.out.println("makeFood...."));
        }
    
        private static void method(Cook cook){
            cook.makeFood();
        }
    }
    
    

    13_Lambda的使用前提

    1.必须保证有一个接口,而且其中的抽象方法有且仅有一个
    2.必须具有上下文环境,才能推导出来Lambda对应的接口

    14_函数式接口的定义和使用

    函数式接口: 接口当中有且仅有一个抽象方法
    @FunctionalInterface注解:用来检测一个接口是不是函数式接口

    编译的时候,写上这个注解:
    1.如果是函数式接口,那么编译通过。
    2.如果不是函数式接口,那么编译失败

    注意事项:
    @FunctionalInterface注解是可选的,就算不用这个注解,只要保证接口满足函数式接口的定义要求,也照样是函数式接口

    @FunctionalInterface
    public interface MyInterface {
        void method();
    }
    
    

    15_Lambda与匿名内部类的区别

    语法糖
    Lambda表达式并不是匿名内部类的“语法糖”
    语法糖:代码的写法更加简便,但其实原理不便。
    例如:
    1.方法当中的可变参数,底层仍然是一个数组
    2.增强for循环用于java.lang.Iterable实现类型时,底层仍然是一个迭代器
    3.自动装箱、自动拆箱

    Lambda表达式和匿名内部类存在根本区别,并非语法糖
    区别:

    1. 所需的类型不一样
      如果是匿名内部类,那么用接口、抽象类、普通的类
      如果是Lambda表达式,则必须是接口
    2. 使用的限制不同
      如果接口当中有且仅有一个抽象方法,那么可以使用Lambda表达式,也可以使用匿名内部类
      但是如果接口当中抽象方法不唯一,则只能使用匿名内部类,不能使用Lambda表达式
    3. 实现原理不同
      匿名内部类,其实就是一个类,编译之后,直接产生一个单独的.class字节码文件
      Lambda表达式,编译之后,没有单独的.class字节码文件,对应的字节码会再运行的时候才会动态生成

    16_接口的组成部分

    1. 常量
    2. 抽象方法
    3. 默认方法 (修饰符default) java8
    4. 静态方法 java8
    5. 私有方法 java8

    17_接口默认方法的问题引出

    案例1:默认方法使用

    public interface MyInterface {
        void method1();
        void method2();
        //现在需要重新定义一个方法,子类MyInterfaceImplA、MyInterfaceImplB都需要实现
        //void methodNew();
    }
    
    public class MyInterfaceImplA implements MyInterface{
        @Override
        public void method1() {
        }
        @Override
        public void method2() {
        }
        //重写接口的抽象方法
        @Override
        public void methodNew(){
        }
    }
    
    public class MyInterfaceImplB implements MyInterface{
        @Override
        public void method1() {
        }
        @Override
        public void method2() {
        }
        //重写接口的抽象方法
        @Override
        public void methodNew(){
        }
    }
    

    接口升级:本来是2个抽象方法,现在需要编程3个抽象方法
    接口的实现类当中必须对接口所有的抽象方法都要覆盖重写,除非实现类是一个抽象类
    根据设计模式当中的开闭原则:对扩展开放,对修改关闭
    从java8开始,接口当中允许定义default默认方法
    常量的修饰符:public static final (都可以省略)
    抽象方法的修饰符:public abstract (都可以省略)
    默认方法的修饰符:public default void(public可以省略,default不能省略)

    可使用java8提供的默认方法,解决接口中无须让各个实现类不重写接口中的抽象方法,使用默认方法

    public interface MyInterface {
        void method1();
        void method2();
        //现在需要重新定义一个方法
        //void methodNew();
    }
    
    public class MyInterfaceImplA implements MyInterface{
        @Override
        public void method1() {
        }
        @Override
        public void method2() {
        }
    }
    
    public class MyInterfaceImplB implements MyInterface{
        @Override
        public void method1() {
        }
        @Override
        public void method2() {
        }
    }
    

    测试方法

    public class Demo {
        public static void main(String[] args) {
            MyInterface myInterface = new MyInterfaceImplA();
            //myInterface.method1();
            //myInterface.method2();
            myInterface.methodNew();
        }
    }
    

    18_接口默认方法的定义和使用

    /**
     * 接口的实现类当中必须对接口所有的抽象方法都要覆盖重写,除非实现类是一个抽象类
     * 接口升级:本来是2个抽象方法,现在需要编程3个抽象方法
     *
     * 设计模式当中的开闭原则:对扩展开放,对修改关闭
     *
     * 从java8开始,接口当中允许定义default默认方法
     * 常量的修饰符:public static final (都可以省略)
     * 抽象方法的修饰符:public abstract (都可以省略)
     * 默认方法的修饰符:public default void(public可以省略,default不能省略)
     * 
     *  默认方法可以有方法体实现
     *  默认方法也可以进行覆盖重写,去掉default关键字,重新指定大括号方法体
     */
    public interface MyInterface {
        void method1();
        void method2()
        public default void methodNew(){
            System.out.println("默认方法");
        };
    }
    
    public class Demo01 {
        public static void main(String[] args) {
            MyInterface myInterface = new MyInterfaceImplA();
            //myInterface.method1();
            //myInterface.method2();
            myInterface.methodNew();
        }
    }
    

    19_接口静态方法的定义和使用

    public interface Animal{
        public abstract void eat();// 抽象方法
        public static Animal getAnimal(){
            return new Cat();
        }
    }
    
    public class Cat implements Animal{
        public void eat(){
        }
    }
    
    public class Dog  implements Animal{
        public void eat(){
        }
    }
    
    public class Demo{
        public static void main(String[] args){
            Animal animal = Animal.getAnimal();
            animal.eat();
        }
    }
    
    image.png

    20_接口静态方法在Java9中的应用

    集合接口的工厂静态方法:of
    java8 当中接口中可以定义的静态方法
    这个特性在java9中得以广泛应用

    public static void main(String[] args) {
            //普通写法
            List<String> list = new ArrayList<>();
            list.add("曹操");
            list.add("刘备");
            list.add("关羽");
            list.add("张飞");
            System.out.println(list);
    
            //匿名内部类
            List<String> list2 = new ArrayList<String>(){
                {
                    add("曹操");
                    add("刘备");
                    add("关羽");
                    add("张飞");
                }
            };
            System.out.println(list2);
    
            //java 9 写法
            //静态
            //list
            List<String> list3 = List.of("aa","bb","cc","dd");
            System.out.println(list3);
    
            //set
            Set<String> set = Set.of("aa","bb","cc","dd");
            System.out.println(set);
    
            //map
            Map<String,Object> map = Map.of("k1","v1");
            System.out.println(map);
        }
    

    21_接口私有方法的定义和使用

    22_接口的组成梳理

    在java 9当中,定义一个接口,基本组成都有:

    java7或者更老的版本中:
    1. 常量:public static final (都可以省略)
    2. 抽象方法:public abstract (都可以省略)

    java 8 新特性:

    1. 常量:public static final (都可以省略)
    2. 抽象方法:public abstract (都可以省略)
      3. 默认方法:public default (public可以省略,default不能省略,必须有方法体)
      4. 静态方法:public static (public可以省略,static不能省略,必须有方法体)

    java 9 新特性:

    1. 常量:public static final (都可以省略)
    2. 抽象方法:public abstract (都可以省略)
    3. 默认方法:public default (public可以省略,default不能省略,必须有方法体)
    4. 静态方法:public static (public可以省略,static不能省略,必须有方法体)
      5. 私有方法:
      a. 私有的成员方法:private (private 不能省略)
      b. 私有的静态方法:private static (private static 不能省略)

    Lambda表达式必须有上下文推导:
    1.根据调用方法的参数推导得知Lambda对应的接口
    2.根据局部变量的赋值来推导得知相应的接口

    相关文章

      网友评论

          本文标题:java8 - java9 新特性 (一)

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