Lambda

本篇记录了Java8新特性Lambda表达式的使用以及函数式接口

Lambda表达式的基础语法:Java8中引入了一个新的操作符 “->” 该操作符称为箭头操作符

箭头操作符将Lambda表达式拆分成两部分:

  • 左侧:Lambda表达式的参数列表
  • 右侧:Lambda表达式中所需执行的功能,即Lambda体

语法格式

  1. 无参数,无返回值

    1
    () -> System.out.println("Hello Lambda");
  2. 有一个参数,无返回值

    1
    (x) -> System.out.println(x);
  3. 若只有一个参数,小括号可以省略不写

    1
    x -> System.out.println(x);
  4. 有两个以上的参数,有返回值,并且Lambda体中有多条语句

    1
    2
    3
    4
    Comparator<Integer> com = (x, y) ->{
    System.out.println("函数式接口");
    return Integer.compare(x, y);
    };
  5. 若Lambda体中只有一条语句,return和大括号都可以省略不写

    1
    2
    Comparator<Integer> coms = (Integer x, Integer y) -> Integer.compare(x, y);
    // Comparator<Integer> com = Integer::compare;
  6. Lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器可以通过上下文推断出,数据类型,即“类型推断”。

    1
    Comparator<Integer> coms = (x, y) -> Integer.compare(x, y);

Lambda表达式需要“函数式接口”的支持

函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。可以使用注解@FunctionalInterface修饰,可以检查是否是函数式接口。

内置函数式接口

Java8中帮我们写好了函数式接口,无需我们自己定义

四大核心函数式接口
函数式接口 参数类型 返回类型 用途
Consumer<T>
消费性接口
T void 对类型为T的对象应用操消费型接口 作,包含方法:void accept(I t)
Supplier<T>
供给型接口
T 返回类型为T的对象,包含方法: T get();
Punction<T, R>
函数性接口
T R 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t);
Predicate<T>
断定型接口
T boolean 确定类型为T的对象是否满足某约束,并返回boolean值,包含方法boolean test(T t);

代码演示:

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
public class LambdaTest {
@Test
public void test1() {
eat(36, m -> System.out.println("吃红烧鱼,每次消费" + m + "元"));
}

@Test
public void test2() {
String hello_world = strHandler("Hello World", str -> str.substring(6, str.length()));
System.out.println(hello_world);
}

@Test
public void test3() {
List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100));
numList.forEach(System.out::println);
}

@Test
public void test4() {
List<String> list = Arrays.asList("Hello", "no", "ok", "java");
List<String> strings = filterString(list, s -> s.length() > 2);
strings.forEach(System.out::println);
}

// 消费型接口
public void eat(double money, Consumer<Double> con) {
con.accept(money);
}

// 供给型接口
public List<Integer> getNumList(int num, Supplier<Integer> supplier) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
list.add(supplier.get());
}
return list;
}

// 函数性接口
public String strHandler(String str, Function<String, String> fun) {
return fun.apply(str);
}

// 断言型接口
// 将满足条件的字符串,放入集合中
public List<String> filterString(List<String> list, Predicate<String> predicate) {
ArrayList<String> strList = new ArrayList<>();
for (String s : list) {
if (predicate.test(s)) {
strList.add(s);
}
}
return strList;
}
}
其他接口
函数式接口 参数类型 返回类型 用途
BiFunction<T, U, R>
消费性接口
T,U R 对类型为T,U参数应用操作,返回R类型的结果。包含方法为R apply(T t, U u);
UnaryOperator<T>
(Function子接口)
T T 对类型为T的对象进行一元运算,并返回T类型的结果。包含方法为T apply(I t);
BinaryOperator<T>
(BiFunction子接口)
T,T T 对类型为T的对象进行二元运算,并返回T类型的结果。包含方法为T apply(T t1, T t2);
BiConsumer<T, U> T,U void 对类型为T, U参数应用操作。包含方法为void accept(T t, U u)
ToIntFunction<T>
ToLongFunction<T>
ToDoubleFunction<T>
T int
long
double
分别计算int、long、double、值的函数
IntFunction<R>
LongFunction<R>
DoubleFunction<R>
int
long
double
R 参数分别为int、long、double类型的函数

方法引用

三种语法格式

  1. 对象::实例方法
  2. 类::静态方法名
  3. 类::实例方法名

注意:

  1. Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保一致。
  2. 若Lambda参数列表中的第一参数式实例方法的调用者,而第二个参数式是实例方法的参数时,可以使用ClassName::method

构造器引用

格式:ClassName::new

注:需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致!

数组引用

格式:Type[]::new

0%