Lambda表达式与函数式编程探索

版权声明:代码自由使用 https://blog.csdn.net/qq_33745102/article/details/85067648

Java 8引入流机制和Lambda表达式之后,两者配合地可谓是天衣无缝,本来想看看Java流库有什么东西,可是全是Lambda表达式,晕死,看来得好好了解一下Lambda了!

函数式编程

在文献2中,作者由Swing中的ActionListener来引入Lambda的概念。比如:

button.addActionListener(new ActionListener() {
 	public void actionPerformed(ActionEvent event) {
 		System.out.println("button clicked");
    }
});

这个语法是不知道从什么时候引入的Java匿名类,在上述代码里,它新创建了一个ActionListener类,并重写了actionPerformed的方法。实际上ActionListener。这个类只有这一个方法,目的就是让此类的使用者重写方法来完善按钮按下的具体动作。

ActionListener这种接口其实功能相当单一,其除了System.out…那行代码其他的全部可以通过接口声明由编译器自动推断。那么,这个模板代码是一个冗余的存在。Lambda的目的就是干掉它。哦,对了,ActionListener就是函数式接口,函数式接口简单说就是只有一个方法的接口。

那么接下来的代码可能大多数人都见过:

 button.addActionListener(event->System.out.println("button clicked"));

解析一下它的结构,event是参数,->代表这是一个Lambda表达式,后面是逻辑语句,多上代码的话可以用{}来包围。
那么event->System.out.println("button clicked")这块代码其实就代替了以上的匿名内部类,并且返回的同样也是一个ActionListener,因此可以是这个样子。

  ActionListener listener=event->System.out.println("button clicked")

Lambda表达式是代码块,类型就是函数式接口,我之前看到过很多类似的函数式接口如Predicate,Consumer等,部分还应用到了泛型。

但是Lambda表达式在我初学时,根本就没有办法看。因为看不懂,不过现在我可以在脑海里构造这样一个映射:

event->System.out.println("button clicked")

==

new ActionListener() {
     	public void actionPerformed(ActionEvent event) {
     		System.out.println("button clicked");
        }
    }

为了深入理解这一点,可以自己构造一个类似Comsumer等JDK内置函数式接口。
以我的英文名Oneslide Icyater为例

public interface Oneslide {
     void callmyname();
}

这个接口只有一个方法,因此这个是个合法的函数式接口,接下来写个Main证明一下:


public class Main {

    public static void main(String args[]) {
       Oneslide icywater=()->{
           System.out.println("oneslide icywater");
       };
       icywater.callmyname();
    }

}

你会得到oneslide icywater这样的输出。可见,Lambda并非什么秘密武器,它只是一个语法糖。前面也说到会和泛型一起用,那么把上面例子变得再复杂一点:

public interface Oneslide<T> {
     String callmyname(T target);
}

上面的接口有了返回值和泛型


public class Main {

    public static void main(String args[]) {
        Oneslide icywater=(name)->{
            String returnName=(String)name+" icywater";
            //简单输出一下吧,不然有点尴尬
            System.out.println(returnName);
            return returnName;
        };
        icywater.callmyname("oneslide");
    }

}

虽然上面的例子是一个很挫地使用了泛型,但是能够充分证明其用法,那么剩下的可以利用
面向对象的概念对语法进行解释了,简化一下代码:

至于为什么引入Lambda呢?我猜大概是其写出来代码所表现出的简洁性超过其不易读的特点。

那么其应用于Stream库

String name="oneslide icywater";
System.out.println(name.chars().filter((w)->w>100).max());

如果你查看filter的声明你会发现Predicate,这里的(w)->w>100)作为一个匿名的Predicate实现类。这几行语句的意思找到编码大于100且最大的字母。

相关链接

  1. Stream并行流性能测试

参考文献

  1. Mastering Lambdas: Java Programming in a Multicore World- Maurice Naftalin
  2. Java 8 Lambdas: Functional Programming For The Masses -Richard Warburton
  3. Core Java Volume II -10th edition

猜你喜欢

转载自blog.csdn.net/qq_33745102/article/details/85067648