Lambda 表达式

Lambda 表达式

lambda表达式的类型是函数,但是在Java中,Lambda表达式是对象,必须依附于对象类型—函数式接口(Function Interface)

JDK8主要内置lambda 函数式接口

  • Consumer::accept 一个参数无返回

    1
    2
    void accept(T t);
    default Consumer<T> andThen(Consumer<? super T> after) // 后面执行的行为
  • Function::apply 一个参数有返回

    1
    2
    3
    R apply(T t);
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) // bef执行结果返回为行为的参数
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) // 行为结果为aft的参数
  • BiFunction::apply 二个参数有返回

    1
    2
    R apply(T t, U u);
    default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after)// 行为结果为aft的参数
  • Predicate::test 一个参数返回布尔

    1
    2
    3
    4
    boolean test(T t);
    default Predicate<T> and(Predicate<? super T> other) // 并且
    default Predicate<T> negate() // 取反
    default Predicate<T> or(Predicate<? super T> other) // 或者
  • Supplier::get 无参数有返回

    1
    T get();
    1
    2
    Supplier<Object> supplier2 = Object::new;
    public Object() {} // new 实际使用的是无参构造方法

lambda实例

1
System.out::println;

函数式接口

@FunctionalInterface

关于函数式接口:

  1. 如果一个接口只有一个抽象方法(除Object的override方法|默认方法和静态方法不会破坏函数式接口的定义),那么接口就是一个函数式接口。
  2. 如果我们在一个接口上声明了FunctionalInterface注解,那么编译器就会按照函数式接口的定义来要求该接口。
  3. 如果某个接口只有一个抽象方法,但我们并没有给该接口声明FunctionalInterface注解,那么编译器依旧会将该接口看作是函数式接口。
1
2
3
4
5
// 函数式接口
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

定义函数式接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface MyParentInterface {
void test();
}

@FunctionalInterface
public interface MyInterface extends MyParentInterface {
void test();
String toString(); // ☑️ override Object
default void defaultMethod() { }// ☑️ 可以使用默认方法
static void staticMethod() {} // ☑️ 可以使用静态方法
}

// 实例
// 编译的时候str会被编译为final
// final String str = "";
String str = "---";
MyInterface myInterface = () -> {
System.out.println("Hello" + str);
};

Java8 新特性

Java8 新特性

  • Lambda 表达式
  • 接口默认方法 default function (使得接口有点类似traits)
  • 接口静态方法 static function
  • 方法引用 (通过::对方法进行引用)
  • 重复注解(同一个地方多次使用同一个注解)
  • 类型推断 (菱形语法)
  • Streams (简化了集合操作|类似管道)
  • Optional (避免null导致的NullPointerException)
  • Comparator 比较器的增强

接口默认方法

为了兼容之前的jdk代码,

1
2
3
4
5
6
7
8
9
// Interable的接口默认方法
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action); // 断言 不为空
for (T t : this) {
action.accept(t);
}
}

接口.super.方法名(); // 直接调用接口的默认方法

方法引用

方法引用实际上是Lambda表达式的一种语法糖

可将方法引用看作是函数指针

方法应用分为四类

  • 类名::静态方法名
  • 实例::实例方法名
  • 类名::实例方法名
  • 类名::new
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 1. 静态方法
public static int compare(int a, int b);
IntTest::compare;

// 2. 实例方法
public int compare(int a, int b);
intTest::compare; // intTest = new IntTest()

// 3. 实例方法 将第一个参数作为调用者
public int compare(IntTest b);
intTest.sort(IntTest::compare) // a::compare(b)

// 4. 构造方法引用
public IntTest() {}
IntTest::new

Optional 避免null的容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// 参数不能是null
Optional<Integer> optional1 = Optional.of(1);
// 参数可以是null
Optional<Integer> optional2 = Optional.ofNullable(null);
// 参数可以是非null
Optional<Integer> optional3 = Optional.ofNullable(2);
// 获得值
optional3.get();

// --------- 比较 -----------
// null 和 empty
Optional<Integer> optional1 = Optional.ofNullable(null);
Optional<Integer> optional2 = Optional.ofNullable(null);
System.out.println(optional1 == optional2);// true
System.out.println(optional1 == Optional.<Integer>empty());// true

Object o1 = Optional.<Integer>empty();
Object o2 = Optional.<String>empty();
System.out.println(o1 == o2);// true

// ---------- ifPresent ----------
Optional<Integer> optional1 = Optional.ofNullable(1);
// 如果不是null,调用Consumer
optional1.ifPresent((t) -> { System.out.println("value is " + t); });

// ---------- orElse 返回值 ----------
Optional<Integer> optional2 = Optional.ofNullable(null);
// orElse
System.out.println(optional2.orElse(1000) == 1000);// true

// ---------- orElseGet 返回行为 ----------
System.out.println(optional1.orElseGet(() -> {
return 1000;
}) == 1);//true

// ---------- orElseThrow 不存在抛出异常 ----------
optional1.orElseThrow(()->{throw new IllegalStateException();});

// ---------- filter 值是否满足Predicate ----------
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> filter1 = optional1.filter((a) -> a == null);
System.out.println(filter1.isPresent());// false

// ---------- map 保存的值进行函数运算,并返回新的Optional ----------
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<String> str1Optional = optional1.map((a) -> "key" + a);
System.out.println(str1Optional.get());// key1
System.out.println(str2Optional.isPresent());// true

// ---------- flatMap 功能与map()相似,flat返回行为类型 ----------
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Optional<String>> str1Optional = optional1.map((a) -> {
return Optional.<String>of("key" + a);
});
Optional<String> str2Optional = optional1.flatMap((a) -> {
return Optional.<String>of("key" + a);
});