Lambda表达式

Lambda表达式出现主要是为了简化代码,若某一个接口只有一个抽象方法,就能使用Lambda表达式来进行简化这个接口的实现类。

Lambda表达式的六种情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 1 无参,无返回值
Runnable r = () -> System.out.println("1");
// 2 一个参数,无返回值
Consumer<String> con = (String s) -> {
System.out.println(s);
};
// 3 数据类型可以省略,编译器有类型推断
Consumer<String> con1 = (s) -> {
System.out.println(s);
};
// 4 若只需要一个参数,小括号能省略
Consumer<String> con2 = s -> {
System.out.println(s);
};
// 5 需要两个或以上的参数,可以有返回值,不只有一条语句
Comparator<Integer> com1 = (o1, o2) -> {
System.out.println(o1);
System.out.println(o2);
return o1.compareTo(o2);
};
// 6 Lambda体只有一条语句,大括号能省略,return也可以省略
Consumer<String> con3 = s -> System.out.println(s);

Java内置的四大核心函数式接口

  1. Consumer<T>

    消费型接口 对T进行操作,不返回结果,方法为 void accept(T t)

  2. Supplier<T>

    供给型接口 不接收参数,返回类型T的数据,方法为 T get()

  3. Function<T,R>

    函数型接口 对类型为T的对象操作,返回R类型的数据,方法为 R apply(T t)

  4. Predicate<T>

    断定型接口 对类型T的数据进行判断,返回Boolean值,方法为 boolean test(T t)

方法引用

在lambda体中引用另一个方法,即用另一个方法来实现lambda体。

使用格式 类(或对象):: 方法名

  1. 对象::非静态方法
  2. 类::静态方法
  3. 类::非静态方法

方法引用的方法的形参列表和返回类型要与lambda一样才能使用该方法引用(针对于前两种格式)

主要是第三种格式有些难懂。

1
2
3
4
5
// 比如   Comparator 中的int compare(T1 t1, T2 t2)
// String中的int t1.compareTo(t2)
// 这种就是形参列表不一样,但是是由t1来调用一个t2参数的方法,所以就可以用第三种格式
// t1作为方法的调用者,t2作为形参
String::compareTo

构造器引用

相当于lambda引用中创建一个对象,调用了一个构造方法。

1
2
3
4
// lambda表达式写法
Supplier<String> str = s -> new String(s);
// 构造器引用的写法
Supplier<String> str = String::new;

Stream流

Stream流的使用主要分为三个步骤。

  1. 创建Stream流。从数据源(集合,数组等)转换成Stream流。
  2. 中间操作。对数据源的数据进行处理。
  3. 终止操作。执行终止操作,就会执行中间操作的处理,产生结果。

创建Stream流

  1. 集合获取Stream流的方法
    • list.stream()串行
    • list.paralleStream() 并行
  2. 数组获取Stream流的方法
    • 通过Arrays的静态方法stream()得到Stream流Arrays.stream(int[])
  3. 通过Stream.of()来获取Stream流
  4. 创建无限流(用于编造数据)
    • Stream.iterate()
    • Stream.generate()

Stream流的中间操作

  1. 筛选与切片

    • filter(Predicate p)

      从流中排除某些元素,即满足Predicate函数的元素

    • limit(n)

      截断流,使其元素不超过给定的元素,即筛选出来的元素不超过n

    • skip(n)

      跳过元素,返回一个除了前n个数据的流,若数据源不足n个,则返回空流

    • distinct()

      通过流生成元素的hashCode和equals方法去除重复的元素

  2. 映射

    • map(Function f)

      接收一个函数作为参数,将元素转换成其他形式或提取信息

    • flatMap(Function f)

      将一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

  3. 排序

    • sorted()

      没有参数,自然排序,默认从小到大的排序,如果操作的元素是类,就会抛出异常,需要该类实现Comparable接口

    • sorted(Comparator com)

      一个Comparator实例,定制排序

Stream流的终止操作

  1. 匹配与查找

    • boolean allMatch(Predicate p)

      检查是否所有元素是否匹配该断定函数接口

    • boolean anyMatch(Predicate p)

      检查是否至少有一个元素匹配该断定函数接口

    • boolean noneMatch(Predicate p)

      检查是否没有元素匹配该断定函数接口

    • findFirst()

      返回第一个元素

    • findAny()

      返回任意一个元素

    • count()

      返回流中的总个数

    • max(Comparator c)

      返回流中的最大值

    • min(Comparator c)

      返回流中的最小值

    • forEach(Consumer c)

      内部迭代

  2. 归约

    • reduce(T identity, BinaryOperator<T> bin)

      可以将流中元素反复结合起来得到一个值,返回这个T类型的值

      比如这个求和的例子list.stream.reduce(0, Integer::sum);

    • reduce(BinaryOperator<T> bin)

      可以将流中元素反复结合起来得到一个值,返回这个Optional<T>类型的值

  3. 收集

collect(Collector c)

将流转换为其他形式的数据源,调用这个Collector接口的方法得到新建数据源

一般使用实现了接口的Collectors的类的方法

常用方法为

  • List<T> toList()

    将元素收集到创建的List

  • Set<t> toSet()

    将元素收集到创建的Set

  • Collection<T> toCollection()

    将元素收集到创建的Collection

  • Long counting()

    计算流中的个数

  • Integer summingInt()

    对流中元素的整数属性求和

  • Double averagingInt()

    求流中的元素Integer属性的平均值

Optional容器类

Optional<T>类是一个容器类,可以报错类型T的值,代表这个值存在。

或者仅仅保存null,表示这个值不存在,可以避免空指针异常

如果值存在,则isPresent()方法返回true,调用get()方法会返回该对象

创建Optional类对象的方法

  1. Optional.of(T t)

    创建一个实例,t是非空的

  2. Optional.isEmpty()

    创建一个空的实例

  3. Optional.ofNullable(T t)

    创建一个实例,t是可以空的

判断Optional中是否包含对象

  1. boolean isPresent()

    判断是否包含对象

  2. void ifPresent(Consumer<? super T> consumer)

    如果有值就会执行Consumer接口的实现代码,并且会作为参数传给它

获取Optional容器的对象

  1. T get()

    如果调用对象包含值,则返回该值,否则抛异常

  2. T orElse(T other)

    如果有值则返回,没有返回指定的other值

  3. T orElseGet(Supplier<? extends T> other)

    如果有值就将其返回,否则返回由Supplier接口实现提供的对象

  4. T orElseThrow(Supplier<? extends X> exceptionSupplier)

    如果有值就将其返回,否则抛出由Supplier接口实现提供的异常