Lambda 表达式

四种方式

定义

/**
定义函数接口

  1. 必须只有一个强制实现的方法
  2. 使用 @FunctionalInterface 标记该接口, 以在编译期检查是否有错误
  3. 可以有一个或多个默认方法
@FunctionalInterface
public interface ICalculator {
    int square(int i);
}

一个参数

一个参数的时候不需要使用()

    @Test
    public void test() {
        ICalculator ic = i -> i * i;
        int res = ic.square(2);
        System.out.println(res);
    }
    

多个参数

多个参数时需要使用()

    @Test
    public void test2() {
        IAddCalculator add = (a, b) -> a + b;
        int res = add.add(1, 2);
        System.out.println(res);
    }

需要参数类型

有时需要指定参数类型,需要使用()

    @Test
    public void test3() {
        IAddCalculator ia = (int a, int b) -> a + b;
        int res = ia.add(1, 2);
        System.out.println(res);
    }

多行

当代码不止一行时,需要使用{}

    @Test
    public void test4() {
        IAddCalculator ia = (a, b) -> {
            int c = a + b;
            return c + a + b;
        };

        int res = ia.add(1, 2);
        System.out.println(res);
    }

函数接口

自己定义

现在有如下代码, 一个函数接口, 已经一个使用改函数接口的类User

@FunctionalInterface
public interface SayHello {
    String sayHi(String username);
}
public class User {
    private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String sayHello(SayHello sayHello) {
        return sayHello.sayHi(this.username);
    }
}

测试代码如下

    @org.junit.Test
    public void test() {
        User user = new User();
        user.setUsername("lisi");

        String hi = user.sayHello(username -> "hello " + username);
        System.out.println(hi);
    }

内置函数接口

上面的代码,核心代码是user.sayHello(username -> "hello " + username);。而为了这一行代码创建一个函数接口有点多此一举。
为了处理这种情况, JDK8提供了函数接口,可以帮我们简化上面的代码

public class Person {
    private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String sayHello(Function<String,String> sayHello){
        return sayHello.apply(username);
    }
}
    @org.junit.Test
    public void test2() {
        Person zs = new Person();
        zs.setUsername("zhang san");
        String s = zs.sayHello(username -> "你好 " + username);
        System.out.println(s);
    }

Person 中的sayHello方法使用了一个Function<String,String>来替代我们自己的函数接口。第一个泛型参数表示输入的参数类型,第二个泛型参数表示输出的参数类型。

其他内置

接口	                输入参数	返回类型	说明
UnaryOperator	    T	    T	    一元函数,输入输出类型相同
Predicate	        T	    boolean	断言
Consumer	        T	    /	    消费一个数据,只有输入没有输出
Function<T,R>	    T	    R	    输入 T 返回 R,有输入也有输出
Supplier	        /	    T	    提供一个数据,没有输入只有输出
BiFunction<T,U,R>	(T,U)	R	    两个输入参数
BiPredicate<L, R>	(L,R)	boolean	两个输入参数
BiConsumer<T, U>	(T,U)	void	两个输入参数
BinaryOperator	    (T,T)	T	    二元函数,输入输出类型相同

方法引用

是什么

方法引用时lambda的一个表达式, 操作符是::

静态引用

当函数接口中只是调用一个静态方法时,采用方法调用的方式可以简化代码

    @Test
    public void test() {
        Function<Integer, String> convert = String::valueOf;
        String res = convert.apply(new Integer(1234));
        System.out.println(res);
    }
    @Test
    public void test2() {
        Consumer<Integer> consumer = System.out::println;
        consumer.accept(new Integer("2234"));
    }
上一篇:巧用控制台提升性能测试


下一篇:...args