java8 Lambda表达式 小结

一、什么是Lambda表达式?

  Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。通俗的理解为通过lambda表达式的本质是语法糖(Syntactic sugar,在计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性),其底层还是通过编译器自动推断并生成匿名类来实现。可以使用更少的代码来实现同样的功能,使代码简洁的同时也使得Java支持闭包的功能。

二、Lambda表达式的语法:

lambda 表达式的语法格式如下:

(parameters) -> expression   或    (parameters) ->{ statements; }
  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。

三、Lambda表达式的应用:

接口类lambda方式使用:

lambda本质是 (parameters) -> expression; 或者 (parameters) -> { statements; }。即() -> {},等同于 new Interface(){}

public class Java8Tester {
   public static void main(String args[]){
      Java8Tester tester = new Java8Tester();
        
      // 类型声明
      MathOperation addition = (int a, int b) -> a + b;
        
      // 不用类型声明
      MathOperation subtraction = (a, b) -> a - b;
        
      // 大括号中的返回语句
      MathOperation multiplication = (int a, int b) -> { return a * b; };
        
      // 没有大括号及返回语句
      MathOperation division = (int a, int b) -> a / b;
        
      System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
      System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
      System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
      System.out.println("10 / 5 = " + tester.operate(10, 5, division));
        
      // 不用括号
      GreetingService greetService1 = message ->
      System.out.println("Hello " + message);
        
      // 用括号
      GreetingService greetService2 = (message) ->
      System.out.println("Hello " + message);
        
      greetService1.sayMessage("Runoob");
      greetService2.sayMessage("Google");
   }
    
   interface MathOperation {
      int operation(int a, int b);
   }
    
   interface GreetingService {
      void sayMessage(String message);
   }
    
   private int operate(int a, int b, MathOperation mathOperation){
      return mathOperation.operation(a, b);
   }
}

 

 

 Map、List和class的lambda使用

package test;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * Map、List和class的lambda使用
 * lambda本质是 (parameters) -> expression; 或者 (parameters) -> { statements; }。即() -> {},等同于 new Interface(){}
 * @author mengyao
 *
 */
public class Java8Tester2 {
 
    public static void main(String[] args) {
        // ==== 1 ==== Map的lambda示例,jdk8之前的写法就不贴出来了
        Map<String, Integer> map = new HashMap<String, Integer>() {{
            put("spark", 1);
            put("storm", 1);
            put("hadoop", 1);
            put("flink", 1);
        }};
        /**
         * parameters确定
         *         map.forEach参数为java.util.function.BiConsumer<? super String, ? super Integer> action,是一个接口的声明,
         *         实现采用的是for(Map.Entry<K, V> entry : entrySet())将entry的k和v作为参数传递到action.accept(k,v)中 验证,到此k,v参数已确定。
         * expression使用
         *         接下来是给到lambda的expression来使用
         * 所以如下3个map.forEach同理
         */

        map.forEach((k,v) -> System.out.println(k+":"+v));
        map.forEach((k,v) -> {System.out.println(k+":"+v);});
        map.forEach((k,v) -> {
            if (k.equals("spark")) {
                System.out.println(k+":"+v);
            }
        });
        
        System.out.println("====");
        
        // ==== 2 ==== List的lambda示例
        List<String> list = new ArrayList<String>(10) {{
            add("spark");
            add("storm");
            add("hadoop");
            add("flink");
        }};
        // 与map.forEach同理
        list.forEach(System.out::println);//System.out是PrintStream的实例,::println即为调用System.out对象的println方法
        list.forEach(item -> System.out.println(item));
        list.forEach(item -> {System.out.println(item);});
        list.forEach(item -> {
            if (item.equals("spark")) {
                System.out.println(item);
            }
        });
        
        //==== 3 ==== 自定义类的lambda使用
        // 接口类非lambda方式使用
        System.out.println("==== "+new MathService() {
            @Override
            public int plus(int a, int b) {
                return a+b;
            }
        }.plus(1, 2));
        
        // 接口类lambda方式使用1(实现plus方法)
        MathService service = (a,b) -> a+b;
        System.out.println("==== "+service.plus(1, 2));
        // 接口类lambda方式使用2,将接口的实现作为参数
        print((a,b)->a+b);
        
    }
 
    /**
     * 使用接口作为参数,通常方法内部会调用接口的方法
     * @param service
     */
    static void print(MathService service) {
        int a =1,b=2;
        System.out.println(service.plus(a, b));
    }
    
}
 
interface MathService {
    //return a+b
    int plus(int a, int b);
}

其他深入应用

多线程中Runnable接口实现:

// 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 rocks !!") ).start();

使用Java 8 lambda表达式进行事件处理

// Java 8之前:
JButton show =  new JButton("Show");
show.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
    System.out.println("Event handling without lambda expression is boring");
    }
});

// Java 8方式:
show.addActionListener((e) -> {
    System.out.println("Light, Camera, Action !! Lambda expressions Rocks");
});

使用lambda表达式和函数式接口Predicate

除了在语言层面支持函数式编程风格,Java 8也添加了一个包,叫做 java.util.function。它包含了很多类,用来支持Java的函数式编程。其中一个便是Predicate,使用 java.util.function.Predicate 函数式接口以及lambda表达式,可以向API方法添加逻辑,用更少的代码支持更多的动态行为。下面是Java 8 Predicate 的例子,展示了过滤集合数据的多种常用方法。Predicate接口非常适用于做过滤。

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

        System.out.println("Languages which starts with J :");
        filter(languages, (str)->str.startsWith("J"));

        System.out.println("Languages which ends with a ");
        filter(languages, (str)->str.endsWith("a"));

        System.out.println("Print all languages :");
        filter(languages, (str)->true);

        System.out.println("Print no language : ");
        filter(languages, (str)->false);

        System.out.println("Print language whose length greater than 4:");
        filter(languages, (str)->str.length() > 4);
    }

    public static void filter(List<String> names, Predicate<String> condition) {
        for(String name: names)  {
            if(condition.test(name)) {
                System.out.println(name + " ");
            }
        }
    }

计算集合元素的最大值、最小值、总和以及平均值

//获取数字的个数、最小值、最大值、总和以及平均值
List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest prime number in List : " + stats.getMax());
System.out.println("Lowest prime number in List : " + stats.getMin());
System.out.println("Sum of all prime numbers : " + stats.getSum());
System.out.println("Average of all prime numbers : " + stats.getAverage());

 

 

 

 

posted @ 2022-03-17 14:48  程序那点事  阅读(32)  评论(0编辑  收藏  举报