【问题记录】【JDK】Lambda 表达式

1  前言

今儿复习 Java 的一些基本知识,回忆一下 Lambda。

2  应用

Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以取代大部分的匿名内部类,可以写出更简洁、更灵活的代码。尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。作为一种更紧凑的代码风格,使 Java 的语言表达能力得到提升。JDK 也提供了大量的内置函数式接口供我们使用,使得 Lambda 表达式的运用更加方便、高效。

说白了:没它之前,我们传递参数的时候,都是静态的,比如某个对象、某个变量,而现在有了它我们可以传递一个方法、一个动作,也就是更灵活了

【1】从匿名类到 Lambda 的转换:虽然使用 Lambda 表达式可以对某些接口进行简单的实现,但并不是所有的接口都可以使用 Lambda 表达式来实现。Lambda 规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法。

jdk8 中有另一个新特性:default, 被 default 修饰的方法会有默认实现,不是必须被实现的方法,所以不影响 Lambda 表达式的使用。

//匿名类
Runnable runnable1 = new Runnable() {
    @Override
    public void run() {
        System.out.printf("Hello World!");
    }
};
/**
 *1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
 *2.简化参数小括号,如果只有一个参数则可以省略参数小括号
 *3.简化方法体大括号,如果方法条只有一条语句,则可以胜率方法体大括号(如下案例)
 *4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号和rerun关键字:X x= a -> a+3;
 *Lambda 表达式展示:
 */
Runnable runnable2 = ()-> System.out.printf("Lambda 表达式");

【2】原来使用匿名内部类作为参数传递到 Lambda 表达式:

//原来使用匿名内部类作为参数传递
TreeSet ts = new TreeSet<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return Integer.compare(o1.length(),o2.length());
    }
});
//Lambda 表达式作为参数传递
TreeSet<String> ts2 = new TreeSet<>((o1,o2)-> Integer.compare(o1.length(),o2.length()));

【3】Lambda 表达式语法:Lambda 表达式在 Java 语言中引入了一个新的语法元素和操作符。这个操作符为 “->” ,该操作符被称为 Lambda 操作符或剪头操作符。它将 Lambda 分为两个部分:

■ 左侧:指定了 Lambda 表达式需要的所有参数;
■ 右侧:指定了 Lambda 体,即 Lambda 表达式要执行的功能;

【语法格式一】:无参,无返回值,Lambda 体只需要一条语句;

Runnable runnable2 = ()-> System.out.printf("Lambda 表达式"); 

【语法格式二】:Lambda 需要一个参数;

Consumer<String> fun = (args) -> System.out.printf(args);

【语法格式三】:Lambda 只需要一个参数时,参数的小括号可以省略;

Consumer<String> fun = args -> System.out.printf(args);

【语法格式四】:Lambda 需要两个参数,并且有返回值;

BinaryOperator<Long> bo = (x,y)->{    System.out.printf("实现函数接口方法");    return x+y;};

【语法格式五】:当 Lambda 体只有一条语句时,return 与大括号可以省略;

BinaryOperator<Long> bo = (x,y) -> x+y;

【语法格式六】:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”:根据上下文环境推断参数类型;

BinaryOperator<Long> bo = (Long x,Long y)->{    
    System.out.printf("实现函数接口方法");    
    return x+y;
};

【4】遍历集合: 可以调用集合的 forEach(Consumer<? super E> action) 方法,通过 lambda 表达式的方式遍历集合中的元素。Consumer 接口是 jdk 为我们提供的一个函数式接口。

ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, 1,2,3,4,5);
//lambda表达式 方法引用
list.forEach(System.out::println);
list.forEach(element -> {
    if (element % 2 == 0) {
      System.out.println(element);
    }
});

【5】删除集合:通过 removeIf(Predicate<? super E> filter) 方法来删除集合中的某个元素,Predicate 也是 jdk 为我们提供的一个函数式接口,可以简化程序的编写。

ArrayList<Item> items = new ArrayList<>();
Collections.addAll(list, 1,2,3,4,5);
items.removeIf(ele -> ele.getId() == 3);

【6】集合内元素的排序:若要为集合内的元素排序,就必须调用 sort 方法,传入比较器匿名内部类重写 compare 方法,我们现在可以使用 lambda 表达式来简化代码。

ArrayList<Item> list= new ArrayList<>();
Collections.addAll(list, 6,27,7,4,2);
list.sort((o1,o2) -> o1.getId() - o2.getId());

3  小结

好啦,就看到这里,有理解不对的地方欢迎指正哈。

posted @ 2024-02-19 07:14  酷酷-  阅读(10)  评论(0编辑  收藏  举报