jdk8 - jdk9 知识学习 (整理中) day01

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

课程介绍

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

java发展历程

版本号年份/代号新特性(部分举例)
1.01996年
1.11997年JDBC
1.21998年 / Playground(运动场)集合、字符串池
1.32000年 / Kestrel(美洲红隼)JDBC
1.42004年 / Merlin(灰背隼)XML、正则、JDBC3.0、断言、NIO
5.02004年 / Tigger (老虎)泛型、注解、可变参数、枚举
6.02006年 / Mustang (野马)脚本、JDBC 4.0
7.02011年 / Dolphin (海豚)NIO2.0 、try-with-resources
8.02014年3月 / Spider (蜘蛛)接口更新、lambda表达式、方法引用、Stream API、函数式接口、Hashorn、JavaFX、DateTime
9.02017年9月Jigsaw模块化、Jshell、接口小更新

Lambda标准格式

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

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

省略规则

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

如何进行软件开发

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

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

Lambda分析

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

public void run(){
		//方法体
}
  1. 参数列表为空,不需要任何条件就可以执行该方法
  2. 没有返回值,方法不产生任何数据结果
  3. 方法体大括号,这才是关键的方法内容所在

Lambda表达式

() -> System.out.println("线程任务执行”);
  1. 小括号,不需要任何参数,即可直接执行
  2. 箭头指向后面要做的事情
  3. 尖肉后面就好比方法体大括号,代表具体要做的内容

示例

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();
    }
}

4、Lambda实现

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

案例1:排序

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));
    }
}

案例2:

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);
    }
}

上面的表达式可以再简写

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、大括号和分好,都可以省略

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

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

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

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

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

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

接口的组成部分

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

案例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();
    }
}

案例2:静态方法使用

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();
	}
}

集合接口的工厂静态方法: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);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值