lambda表达式与函数式接口初步介绍

2018-03-28  本文已影响0人  pr0metheus

何为Lambda表达式?

Lambada:In programming Languages such as Lisp、python and Ruby Lambda is an operator used to denote anonymous functions or closures,following the usage of lambda calculus.

为何需要Lambda表达式?

例如如下代码在jdk8之前是不存在的:

a.execute(callback(event){
...
})

Lambda表达式基本结构:

(param, param2, param3) -> {
}

注:在这里我们暂时将lambda表达式理解为三部分:参数、分隔符、执行体。

首先我们看一个小例子,如下代码是jdk8之前的风格:

public class SwintTest {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JButton btn = new JButton();
        btn.addActionListener(new ActionListener() { //关键看此处
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("点击了按钮");
            }
        });
        btn.setText("按钮");
        frame.setVisible(true);
        frame.pack();
        frame.add(btn);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

在对比下Jdk8的编程风格:

public class SwintTest {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JButton btn = new JButton();
        btn.addActionListener(event -> System.out.println("点击了按钮")); //关键看此处
        btn.setText("按钮");
        frame.setVisible(true);
        frame.pack();
        frame.add(btn);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

之前我们向按钮安装监听器的方式都是传递一个匿名内部类,这其实很没必要我们真正关心的只是actionPerformed方法中的内容而已,但在Jdk8之前没办法只能这样做。而在Jdk8之后我们不需要再传递匿名内部类了,我们可以直接用Lambda表达式来做作为参数。这里看到event是不是有点疑惑,它没有声明类型,这是因为java编译系统可以智能的推导出类型所以我们把类型省略了而已。

写上类型也没有关系,只是没必要而已如:

(ActionEvent event) -> System.out.println("点击了按钮")

如果要打印多条语句则:

btn.addActionListener((ActionEvent event) -> {
     System.out.println("点击了按钮-1");
     System.out.println("点击了按钮-2");
     System.out.println("点击了按钮-3");
});

我们再看另一个例子:

public class Test1 {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
        //jdk1.4中的循环方式
        for (int i = 0; list != null && i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        System.out.println("----------------");
        //jdk1.5增强型for循环方式
        for (Integer i : list) {
            System.out.println(i);
        }
        System.out.println("----------------");
        //jdk1.8的循环方式
        list.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        });
    }
}

Consumer也是Jdk1.8新增加的接口,并且它是函数接口,那么什么是函数接口呢?

函数接口也是jdk1.8新增加的概念,关于函数式接口我们需要知道如下几个知识点:

对于符合函数式接口定义的接口我们最好加上@FunctionInterface既方便代码阅读也避免出现与此相关的代码问题,例如一个不符合函数式接口定义的接口有@FunctionInterface声明的话,那么IDE就会提示你该接口不符合函数式接口定义,这样在编码阶段就能够避免出现与此相关的代码问题。

上一篇下一篇

猜你喜欢

热点阅读