zoukankan      html  css  js  c++  java
  • Java进阶教程:Lambda表达式与最佳实践

    Java基础教程:Lambda表达式

    引入Lambda

      Java 是一流的面向对象语言,除了部分简单数据类型,Java 中的一切都是对象,即使数组也是一种对象,每个类创建的实例也是对象。在 Java 中定义的函数或方法不可能完全独立,也不能将方法作为参数或返回一个方法给实例

      从 Swing 开始,我们总是通过匿名类给方法传递函数功能,以下是旧版的事件监听代码:

    someObject.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
    
                //Event listener implementation goes here...
    
            }
        });

      在上面的例子里,为了给 Mouse 监听器添加自定义代码,我们定义了一个匿名内部类 MouseAdapter 并创建了它的对象,通过这种方式,我们将一些函数功能传给 addMouseListener 方法

      简而言之,在 Java 里将普通的方法或函数像参数一样传值并不简单,为此,Java 8 增加了一个语言级的新特性,名为 Lambda 表达式

    Lambda表达式简介

      Lambda 表达式是一种匿名函数(对 Java 而言这并不完全正确,但现在姑且这么认为),简单地说,它不用声明、没有名字,也不用说明返回值类型

      Java中的lambda表达式通常采用(argument)->(body),例如

    (arg1, arg2...) -> { body }
    
    (type1 arg1, type2 arg2...) -> { body }
    

      以下是Lambda的一些例子:

    int a, int b) -> {  return a + b; }
    
    () -> System.out.println("Hello World");
    
    (String s) -> { System.out.println(s); }
    
    () -> 42
    
    () -> { return 3.1415 };

    Lambda表达式结构

    让我们了解一下 Lambda 表达式的结构。

    • 一个 Lambda 表达式可以有零个或多个参数
    • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)(a)效果相同
    • 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
    • 空圆括号代表参数集为空。例如:() -> 42
    • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
    • Lambda 表达式的主体可包含零条或多条语句
    • 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
    • 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空。

    函数式接口

      函数式接口是只包含一个抽象方法声明的接口。java.lang.Runnable 就是一种函数式接口,在 Runnable 接口中只声明了一个方法 void run(),相似地,ActionListener 接口也是一种函数式接口,我们使用匿名内部类来实例化函数式接口的对象,有了 Lambda 表达式,这一方式可以得到简化。

    Runnable r = () -> System.out.println("hello world");
    

      当不指明函数式接口时,编译器会自动解释这种转化:

    new Thread(
       () -> System.out.println("hello world")
    ).start();
    

      因此,在上面的代码中,编译器会自动推断:根据线程类的构造函数签名 public Thread(Runnable r) { },将该 Lambda 表达式赋给 Runnable 接口

    以下是一些 Lambda 表达式及其函数式接口:

    Consumer<Integer>  c = (int x) -> { System.out.println(x) };
    
    BiConsumer<Integer, String> b = (Integer x, String y) -> System.out.println(x + " : " + y);
    
    Predicate<String> p = (String s) -> { s == null };

    Lambda表达式举例

    线程初始化

    //旧方法:
    new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello from thread");
    }
    }).start();
    
    //新方法:
    new Thread(
    () -> System.out.println("Hello from thread")
    ).start();

    Swing事件处理

    //Old way:
    button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("The button was clicked using old fashion code!");
    }
    });
    
    //New way:
    button.addActionListener( (e) -> {
        System.out.println("The button was clicked. From Lambda expressions !");
    });

    打印数组所有元素

    //Old way:
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    for(Integer n: list) {
       System.out.println(n);
    }
    
    //New way:
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    list.forEach(n -> System.out.println(n));

    处理数组中的每个元素

    //Old way:
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    for(Integer n : list) {
        int x = n * n;
        System.out.println(x);
    }
    
    //New way:
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    list.stream().map((x) -> x*x).forEach(System.out::println);

    委婉待续......

    参考链接:

    • http://blog.oneapm.com/apm-tech/226.html
  • 相关阅读:
    JAVA,统计字符串里面每个字符出现的次数
    JAVA,遍历HashMap的2种方式,keySet方法和entrySet对象
    JAVA,Map接口常用方法
    JAVA,Collection集合常用API和集合特点
    object类常用方法
    [Algorithm] 双指针应用
    [CV]计算机视觉中值变换、拉普拉斯算子、傅里叶变换
    [CNBlogs]使用Typora和MetaWeblog改善博客园书写体验
    [C#] 动态编程表达式树实现NPOI.IROW快速映射优化
    [CV] 计算机视觉像素位变换(反转变换、对数变换,伽马变换,直方图均衡化)
  • 原文地址:https://www.cnblogs.com/MrSaver/p/9988632.html
Copyright © 2011-2022 走看看