【问题记录】【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 小结
好啦,就看到这里,有理解不对的地方欢迎指正哈。