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

mac2022-06-30  19

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

课程介绍

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

java发展历程

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

Lambda标准格式

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

如何进行软件开发

自己编写二进制汇编语言面向过程面向对象函数式编程思想

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

Lambda分析

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

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

Lambda表达式

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

示例

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表达式和匿名内部类存在根本区别,并非语法糖 区别:

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

接口的组成部分

常量抽象方法默认方法 (修饰符default) java8静态方法 java8私有方法 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); }
最新回复(0)