jdk1.8就带有的Lambda表达式,现在1.9都发布了你不会还没用过吧

时间:2022-08-26 19:10:28

标题对自己说的,做一个程序员虽然只有短短几年,但是每个版本的新特性没有掌握,现在还是一个基层业务开发者,有点挫败。最近开始看书,了解一些原理的东西,借用老板的一句话,写代码要写的有艺术~


  • 替换匿名类

学习java lambda,首先要了解 的就是使用lambda表达式替换匿名类,那就是用“() -> {}”代码块替代了整个匿名类。

例子:

// Java 8之前:
new Thread(new Runnable() {
    @Override
    public void run() {
    System.out.println("Before Java8, too much code for too little to do");
    }
}).start();

// Java 8方式:
new Thread(() -> System.out.println("In Java8, Lambda expression !!") ).start(); // 传递参数: (String str) -> System.out.println(str) 

  • lambda表达式对列表进行迭代
    针对集合类,最常见的操作就是进行迭代,接下来展示如何进行列表循迭代。
// Java 8之前:
List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
for (String feature : features) {
    System.out.println(feature);
}

// Java 8之后:
List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
features.forEach(n -> System.out.println(n));

// 使用Java 8的方法引用更方便,方法引用由::双冒号操作符标示
features.forEach(System.out::println);

除了在语言层面支持函数式编程风格,Java 8也添加了一个包,叫做 java.util.function。它包含了很多类,用来支持Java的函数式编程。其中一个便是Predicate,Predicate接口非常适用于做过滤。


    public static void main(String[] args) {
        List<String> languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");

        // 开头为J
        System.out.println("Languages which starts with J :");
        filter(languages, (str) -> ((String) str).startsWith("J")); // 结尾为 a System.out.println("Languages which ends with a "); filter(languages, (str) -> ((String) str).endsWith("a")); // true System.out.println("Print all languages :"); filter(languages, (str) -> true); // false System.out.println("Print no language : "); filter(languages, (str) -> false); // 长度大于4 System.out.println("Print language whose length greater than 4:"); filter(languages, (str) -> ((String) str).length() > 4); } public static void filter(List<String> names, Predicate condition) { // for (String name : names) { // if (condition.test(name)) { // System.out.println(name + " "); // } // } // 用lambda 迭代替换原本的for循环 names.stream().filter((name) -> (condition.test(name))).forEach((name) -> { System.out.println(name + " "); }); }
  • lambda表达式中加入Predicate

Predicate条件判断通常不是说一个条件,而是有或/且的关系,那么在lambda中,用方法or/and来实现,如下。

Predicate<String> startsWithJ = (n) -> n.startsWith("J");
Predicate<String> fourLetterLong = (n) -> n.length() == 4; 

names.stream().filter(
startsWithJ.and(fourLetterLong.or(startsWithJ)))
.forEach((n) -> System.out.print("nName, which starts with 'J' and four letter long is : " + n)); 
  • Java 8中使用lambda表达式的List Map的处理。

    list处理。

// 不使用lambda表达式为每个订单加上12%的税
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
for (Integer cost : costBeforeTax) {
    cost = cost + .12*cost; 
}

// 使用lambda表达式
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
costBeforeTax.stream().map((cost) -> cost = (int) (cost + .12*cost)).forEach(System.out::println); 

reduce() 函数可以将所有值合并成一个。Map和Reduce操作是函数式编程的核心操作,因为其功能,reduce 又被称为折叠操作。另外,reduce 并不是一个新的操作,你有可能已经在使用它。SQL中类似 sum()、avg() 或者 count() 的聚集函数,实际上就是 reduce 操作,因为它们接收多个值并返回一个值。流API定义的 reduceh() 函数可以接受lambda表达式,并对所有值进行合并。IntStream这样的类有类似 average()、count()、sum() 的内建方法来做 reduce 操作,也有mapToLong()、mapToDouble() 方法来做转换。这并不会限制你,你可以用内建方法,也可以自己定义。在这个Java 8的Map Reduce示例里,我们首先对所有价格应用 12% 的VAT,然后用 reduce() 方法计算总和。

// 为每个订单加上12%的税
// 老方法:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double total = 0;
for (Integer cost : costBeforeTax) {
    double price = cost + .12*cost;
    total = total + price;
}
System.out.println("Total : " + total);

// 新方法:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost).reduce((sum, cost) -> sum + cost).get(); System.out.println("Total : " + bill);
  • lambda 做一个字符串过滤
List<String> strList =  Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp"); 

List<String> filtered = strList.stream().filter(x -> x.length() > 3).collect(Collectors.toList());

filtered.forEach(n -> System.out.println(n));
输出
Java
Scala
Haskell
Lisp
  • 对列表元素的函数使用
    实际代码中免不了循环对集合中的对象进行加工,这里则演示这个点。
// 将字符串换成大写并用逗号链接起来
List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.","Canada");
String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));
System.out.println(G7Countries);
输出
USA, JAPAN, FRANCE, GERMANY, ITALY, U.K., CANADA

以上内容基本可以满足日常使用,还需要了解其他的话可以看一下官方文档,以及一些其他人的研究,愿大家的代码写的更优美。