Lambda表达式
概述
函数式编程思想的一个重要体现,关注对数据进行了什么操作
核心原则
可推导可省略
基本格式
(参数列表)->{代码}
例一
创建线程的时候可以使用匿名内部类的写法:
new Thread(new Runnable(){
@Override
public void run(){
System.out.println("text");
}
}).start();
可以使用Lambda的格式对其进行修改
new Thread(()->{
System.out.println("text");
}).start();
省略规则
参数类型可以省略
方法体只有一句代码时大括号return和唯一一句代码的分号可以省略
方法体只有一个参数时小括号可以省略
Stream流
概述
对集合或数组进行链状流式的操作
常用操作
创建流
单列集合:集合对象.stream()
List<author> authors = getAuthors();
Stream<Author> stream = authors.stream();
数组:Arrays.stream(数组)或者使用Stream.of来创建
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);
中间操作
filter:可以对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中
map:可以把对流中的元素进行计算或转换
例如:
打印所有作家的姓名
List<Author> authors = getAuthors();
authors.stream()
.map(author->author.getName())
.forEach(name->System.out.println(name));
所有年龄加10
List<Author> authors = getAuthors();
authors.stream()
.map(author->author.getAge())
.map(age->age+10)
.forEach(age->System.out.println(age));
distinct:可以去除流中重复操作
例如:
打印所有作家的名字,要求不能有重复元素
List<Author> authors = getAuthors();
authors.stream()
.distinct()
.forEach(author->System.out.println(author.getName()));
注意:distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以要注意重写equals方法
终结操作
forEach:对流中的元素进行遍历操作,我们通过传入的参数去指定对遍历到的元素进行什么具体操作
例如:
输出所有作家的名字
List<Author> authors = getAuthors();
authors.stream()
.distinct()
.forEach(author->System.out.println(author.getName()));
collect:把当前流转化成一个集合
例子:
获取一个存放所有作家名字的List集合
获取一个所有书名的Set集合
获取一个Map集合,key为作者名,value为List
Optional
概述
在编写代码的时候出现最多的就是空指针异常。所以在很多情况下我们需要做各种非空的判断。
例如:
过多的判断会让代码臃肿
很多函数式编程相关API都用到了Option,如果不会Option会对函数式编程造成影响
使用
创建对象
Optional就好像是包装类,可以把我们的具体数据封装到Optional对象内部,然后我们去使用封装好的方法操作封装进去的数据就可以避免空指针异常
一般使用Optional的静态方法ofNullable来把数据封装成一个Optional对象。
安全的消费值
ifPresent方法判断封装的数据是否为空,不为空时才会执行具体的消费代码
例如:
函数式接口
概述
只有一个抽象方法的接口称之为函数接口
JDK的函数式接口都加上了@FuntionalInterface注解进行标识。无论有没有这个注解,只要接口中有一个抽象方法,都是函数式接口。