—— lambda 表达式
概念
- lambda 表达式是一个匿名函数,可以把 lambda 表达式理解为是一段可以传递的代码。
- 更简洁、更灵活,使 Java 的语言表达能力得到了提升
- lambda 表达式是作为接口的实现类的对象(万事万物皆对象)
使用语法
- 例:
(o1,o2) -> Integer.compare(o1,o2)
- ->:lambda 操作符 或 箭头操作符
- -> 的左边:lambda 形参列表,对应着要重写的接口的抽象方法的形参列表
- -> 的右边:lambda 体,对应着接口的实现类要重写的方法的方法体
语法格式
- 无参,无返回值
new Thread(() -> {
System.out.println("hello");
}).start();
- 有一个参数,无返回值
Consumer<Integer> a = (Integer integer) -> {
System.out.println(integer);
};
- 数据类型可以省略
Consumer<Integer> a = (integer) -> {
System.out.println(integer);
};
- 只需要一个参数时,参数小括号可以省略
Consumer<Integer> a = integer -> {
System.out.println(integer);
};
- 需要两个及以上的参数,并且有返回值
Comparator<Integer> comparator = (o1, o2) -> {
return o1 - o2;
};
- 当只有一条语句时,return 和 大括号都有,则都可以省略
Comparator<Integer> comparator = (o1, o2) -> o1 - o2;
—— 函数式接口
概念
- 如果接口中只声明有一个抽象方法,则此接口就称为函数式接口
- 只有给函数式接口提供实现了类的对象时,才可以使用 lambda 表达式
- 注解:
@FunctionalInterface
Java8 后引入 - 包路径:java.util.function
四大核心函数式接口
—— 方法引用 / 构造器引用
概念
- 方法引用可以看做是基于 lambda 表达式的进一步刻画
- 当需要提供一个函数式接口的实例时,我们可以使用 lambda 表达式提供此实例
- 满足一定条件的情况下,可以使用方法引用 或 构造器引用替换 lambda 表达式
- 方法引用作为了函数式接口的实例
使用语法
- 格式:
类(或者对象):: 方法名
- 举例:
Integer :: compare
Lists.newArrayList("a", "b", "c").forEach(System.out::println)
构造器引用
// 无参构造器
Supplier<User> userSupplier = User::new;
// 有参构造器
Function<Integer, User> userFunction = User::new;
—— Stream 流式计算
概念
- Stream 是数据渠道,用于操作数据源(集合、数组)所生成的元素序列
- Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤、和数据映射等操作
- 使用 Stream API 对集合数据进行操作,类似于使用 SQL 执行的数据库查询
Stream 和 Collection 区别
- Collection 是一种静态的内存数据结构,讲的是数据;而 Stream 是计算。前者面向内存,存储在内存中;后者面向 CPU,通过 CPU 实现计算
- Stream 不会自己存储元素、不会改变源对象
- Stream 操作是延迟执行。这意味着他们会等到需要结果的时候才执行。即一旦执行终止操作,这就执行中间操作链,并产生结果
- Stream 一旦执行了终止操作,就不能再调用其他中间操作或终止操作了
操作
PersonBo personBo1 = new PersonBo(1, "张三");
PersonBo personBo2 = new PersonBo(2, "李四");
PersonBo personBo3 = new PersonBo(3, "王五");
PersonBo personBo4 = new PersonBo(4, "赵六");
List<PersonBo> list = new ArrayList<>();
list.add(personBo1);
list.add(personBo2);
list.add(personBo3);
list.add(personBo4);
// filter 过滤(返回还是对象)
list.stream().filter(t -> {
return t.getId() % 2 == 0;
}).forEach(System.out::println);
// match:anyMatch、allMatch、noneMatch 对流中的元素进行匹配
boolean y = list.stream().anyMatch(personBo -> {
return personBo.getName().contains("y");
});
// map 将集合中的元素类型,转换成另一种数据类型
list.stream().map(PersonBo::getId).forEach(System.out::println);
// sorted 根据字段属性进行排序
list.stream().sorted((u1, u2) -> {
return u2.getId().compareTo(u1.getId());
}).map(PersonBo::getId).forEach(System.out::println);
// limit限制数————collect将map单个映射转为list集合
list.stream().map(t -> {
return t.getId();
}).limit(1).forEach(System.out::println);
// distinct 对流中的元素进行去重
list.stream().distinct().forEach(System.out::println);
// partitioningBy 根据判断的值为true还是false分为两组
Map<Boolean, List<PersonBo>> collect = list.stream().collect(Collectors.partitioningBy(personBo -> {
return personBo.getId() > 3;
}));
// groupingBy 将数据分组成多个key的形式(即groupby分组)
Map<Integer, List<PersonBo>> collect1 = list.stream().collect(Collectors.groupingBy(PersonBo::getId));
// reduce 计算集合总数
Integer sum = list.stream().map(PersonBo::getId).reduce(Integer::sum).get();
System.out.println(sum);