zoukankan      html  css  js  c++  java
  • Java中Lambda基础

    在了解Lambda之前,我们先回顾一下Java的方法。

    Java的方法分为实例方法,例如Integer定义的equals()方法:

    public final class Integer {
        boolean equals(Object o) {
            ...
        }
    }

    以及静态方法,例如Integer定义的parseInt()方法

    public final class Integer {
        public static int parseInt(String s) {
            ...
        }
    }

    无论是实例方法,还是静态方法,本质上都相当于过程式语言的函数。例如C函数:

    char* strcpy(char* dest, char* src)

    只不过Java的实例方法隐含地传入了一个this变量,即实例方法总是有一个隐含参数this

    函数式编程(Functional Programming)是把函数作为基本运算单元,函数可以作为变量,可以接收函数,还可以返回函数。历史上研究函数式编程的理论是Lambda演算,所以我们经常把支持函数式编程的编码风格称为Lambda表达式

    Lambda表达式

    在Java程序中,我们经常遇到一大堆单方法接口,即一个接口只定义了一个方法:

    • Comparator
    • Runnable
    • Callable

    Comparator为例,我们想要调用Arrays.sort()时,可以传入一个Comparator实例,以匿名类方式编写如下:

    String[] array = ...
    Arrays.sort(array, new Comparator<String>() {
        public int compare(String s1, String s2) {
            return s1.compareTo(s2);
        }
    });

    上述写法非常繁琐。从Java 8开始,我们可以用Lambda表达式替换单方法接口。改写上述代码如下:

    public class Main {
        public static void main(String[] args) {
            String[] array = new String[] { "Apple", "Orange", "Banana", "Lemon" };
            Arrays.sort(array, (s1, s2) -> {
                return s1.compareTo(s2);
            });
            System.out.println(String.join(", ", array));
        }
    }

    观察Lambda表达式的写法,它只需要写出方法定义:

    (s1, s2) -> {
        return s1.compareTo(s2);
    }

    其中,参数是(s1, s2),参数类型可以省略,因为编译器可以自动推断出String类型-> { ... }表示方法体,所有代码写在内部即可。Lambda表达式没有class定义,因此写法非常简洁。

    如果只有一行return xxx的代码,完全可以用更简单的写法:

    Arrays.sort(array, (s1, s2) -> s1.compareTo(s2));

    返回值的类型也是由编译器自动推断的,这里推断出的返回值是int,因此,只要返回int,编译器就不会报错。

    FunctionalInterface

    我们把只定义了单方法的接口称之为FunctionalInterface,用注解@FunctionalInterface标记。例如,Callable接口:

    @FunctionalInterface
    public interface Callable<V> {
        V call() throws Exception;
    }

    再来看Comparator接口:

    @FunctionalInterface
    public interface Comparator<T> {
    
        int compare(T o1, T o2);
    
        boolean equals(Object obj);
    
        default Comparator<T> reversed() {
            return Collections.reverseOrder(this);
        }
    
        default Comparator<T> thenComparing(Comparator<? super T> other) {
            ...
        }
        ...

    虽然Comparator接口有很多方法,但只有一个抽象方法int compare(T o1, T o2),其他的方法都是default方法或static方法

    另外注意到boolean equals(Object obj)Object定义的方法,不算在接口方法内。因此,Comparator也是一个FunctionalInterface

    小结:

    单方法接口被称为FunctionalInterface

    接收FunctionalInterface作为参数的时候,可以把实例化的匿名类改写为Lambda表达式,能大大简化代码。

    Lambda表达式的参数和返回值均可由编译器自动推断。

    注意事项:

  • 相关阅读:
    每天一个linux命令(54):sftp命令
    每天一个linux命令(53):wget命令
    每天一个linux命令(52):scp命令
    每天一个linux命令(51):rcp命令
    每天一个linux命令(50):telnet命令
    每天一个linux命令(49):ss命令
    每天一个linux命令(48):netstat命令
    每天一个linux命令(46):ping命令
    Springmvc常见问题
    MP实战系列(十)之SpringMVC集成SpringFox+Swagger2
  • 原文地址:https://www.cnblogs.com/cy0628/p/14850840.html
Copyright © 2011-2022 走看看