我是南城余!阿里云开发者平台专家博士证书获得者!
欢迎关注我的博客!一同成长!
一名从事运维开发的worker,记录分享学习。
专注于AI,运维开发,windows Linux 系统领域的分享!
JDK认知
Java版本迭代概述
备注:LTS(Long-term Support)即长期支持
名词解释:Oracle JDK和Open JDK
如何学习新特性
对于新特性,我们应该从哪几个角度学习新特性呢?
- 语法层面:
- 比如JDK5中的自动拆箱、自动装箱、enum、泛型
- 比如JDK8中的lambda表达式、接口中的默认方法、静态方法
- 比如JDK10中局部变量的类型推断
- 比如JDK12中的switch
- 比如JDK13中的文本块
- API层面:
- 比如JDK8中的Stream、Optional、新的日期时间、HashMap的底层结构
- 比如JDK9中String的底层结构
- 新的 / 过时的 API
- 底层优化
- 比如JDK8中永久代被元空间替代、新的JS执行引擎
- 比如新的垃圾回收器、GC参数、JVM的优化
Lambda表达式
使用场景
- 在给函数式接口提供实例时,都可以使用lambda表达式
- Predicate<T>:用于输入一个参数,返回一个布尔值的情况。比如判断一个数字是否大于 10,可以通过 Predicate 实现。
- Consumer<T>:用于接收一个参数,但没有返回值的情况。比如对列表中的每个元素进行操作的场景。
- Function<T, R>:用于输入一个参数,并返回一个结果的情况。比如将字符串转为大写,可以用 Function 实现。
- Supplier<T>:用于不接收任何参数,而是提供一个返回值的情况。比如每次调用时返回一个新的随机数。
格式
->:Lambda 操作符或箭头操作符
->的左边:Lambda形参列表,对应着重要的接口中的抽象方法的形参列表
->的右边:Lambda体,对应着接口的实现类要重写的方法的方法体
本质
》一方面,Lambda表达式作为接口的实现类的对象。
》另一方面,Lambda表达式是一个匿名函数
函数式接口
》如果接口中只声明一个抽象方法,则此接口就称为函数式接口
》因为只有函数式接口提供实现类的对象时,我们才可以使用lambda表达式
API中函数式接口所在的包
jdk8中声明的函数式接口都在java.util.function包下
4个基本的函数式接口
接口 对应的抽象方法
消费类型接口 Consumer<T> void accept(T t)
供给类型接口 Supplier<T> T get()
函数类型接口 Function<T,R> R apply(T t)
判断类型接口 Predicate<T> boolean test(T t)
总结
->的左边:lambda形参列表,参数的类型都可以省略,如果形参只有一个,则()也可以省略
->的右边:lambda体,对应着重写的方法的方法体。如果方法体中只有一行执行语句,则一对{}可以省略
如果有return关键字,则必须一并省略。
方法引用
》方法引用,可以理解基于lambda表达式的进一步刻画
》当需要提供一个函数式接口的实例时,我们可以使用lambda表达式提供此实例
》当满足一定的条件的情况下,我们还可以使用方法引用或构造器引用替换lambda表达式
本质
方法引用作为类函数式接口的实例。
格式
类 (或对象) :: 方法名
》对象 :: 实例方法
要求:函数式接口中的抽象方法a与其内部实现时调用的对象的某个方法b的形参列表和返回值类型都相同(或一致)
此时,可以考虑使用方法b实现方法a的替换、覆盖。此替换或覆盖即为方法引用
》类 :: 静态方法
》类 :: 实例方法
构造器引用
格式
类名 :: new
说明
》调用了类名对应的类中的某一个确定的构造器
》具体调用的构造器取决于函数式接口的抽象方法的形参列表
数组引用
格式
数组名[] :: new
Stream API 与 集合框架
》Stream API 关注的是多个数据的计算(排序、查找、过滤、映射、遍历等),面向CPU的
》Stream API之于集合,类似于SQL之于数据库查询
使用说明
- Stream自己不会存储元素
- Stream不会改变源对象。相反,他们会返回一个特有结果的新Stream
- Stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行,即一旦执行终止
- Stream一旦执行了终止操作,就不能在调用其他中间件操作,或终止操作。