JAVA8 Lambda表达式

2020-05-31 16:01:39来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

JAVA8 Lambda表达式

简介

在函数式编程中函数可以在程序中传来传去,甚至数字也可以用函数表示,而在面向对象中必须将这些函数封装成方法,通过调用方法实现。所以 Java 从邻居那拿来了 Lambda。

Java8 引入了 Lambda 表达式,它使代码变得更简洁和高效,更方便的让我们在计算机上说话,长得就像下面那样。

s -> s + s;
(s1, s2) -> { return s1 + s2; };

Lambda可以用于实现只有一个抽象方法的接口,在接口加上 @FunctionalInterface 注解可以提醒我们接口只有一个抽象方法 。下面是 Java 的 Comparator 两种实现方式,以前的写法是实现一个匿名类。

//comparator2 更简洁
Comparator<String> comparator1 = (s1, s2) -> s1.compareTo(s2);
Comparator<String> comparator2 = String::compareTo;

几种常见函数

Java 本身提供了 Function、BiFunction、Predicate、Consumer、Supplier 等几种函数,介绍如下。

函数 格式 说明
Function Function<T, R> 接收一个参数,有一个返回值
BiFunction BiFunction<T, U, R> 接收两个参数,有一个返回值
Predicate Predicate<T> 接收一个参数,返回值boolean类型
Consumer Consumer<T> 接收一个参数,没有返回值
Supplier Supplier<T> 没有参数,有一个返回值

Function

Function<T, R> 中 T 是传入参数的类型,R 是返回值的类型。源码中主要有 apply、compose、andThen 方法。

@FunctionalInterface
public interface Function<T, R> {

    //执行函数
    R apply(T t);

    //先执行 before 函数,再执行当前函数。
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    //先执行当前函数,再执行 after 函数
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
}

示例如下。

Function<Integer, String> fun1 = integer -> String.valueOf(integer + integer);
Function<String, BigDecimal> fun2 = s -> new BigDecimal(s + ".5");
//执行函数
String s = fun1.apply(1);
//两个函数中都是 fun1 先执行
BigDecimal decimal1 = fun1.andThen(fun2).apply(1);
BigDecimal decimal2 = fun2.compose(fun1).apply(1);

执行后 s 值是 2,decimal1 和 decimal2 值是 2.5。

BiFunction

BiFunction<T, U, R> 中 T 和 U 是传入的参数类型,R 是返回值类型。源码中有 apply、andThen 方法,因为 BiFunction 需要两个参数,所以没有 compose 方法。

@FunctionalInterface
public interface BiFunction<T, U, R> {
    //执行方法
    R apply(T t, U u);
	//先执行当前函数,再执行 after 函数
    default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t, U u) -> after.apply(apply(t, u));
    }
}

示例如下。

BiFunction<Integer, Integer, String> biFunction = (param1, param2) -> String.valueOf(param1 * param2 + 1);
Function<String, BigDecimal> fun1 = s -> new BigDecimal(s + ".5");
//先执行 biFunction,再执行 fun1
BigDecimal decimal3 = biFunction.andThen(fun1).apply(1, 2);

Predicate

Predicate<T> 中 T 是 传入参数的类型,返回一个 boolean 类型的值。源码中主要有 test、and、negate、or、isEqual 方法。

@FunctionalInterface
public interface Predicate<T> {
	//执行方法
    boolean test(T t);
	//关系运算符 &&,当 test 的结果为 false 时直接结束,不运算 other
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    //关系运算符 !
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }
	//关系运算符 ||,当 test 的结果为 true 时直接结束,不运算 other
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
	//判断相等
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

示例如下。

//为空返回 true
Predicate<String> isNull = Objects::isNull;
//不为空返回 true
Predicate<String> nonNull = Objects::nonNull;
boolean bool = isNull.or(nonNull.negate()).and(Predicate.isEqual("123")).test("123");

执行后 bool 的值为 false,执行后 isNull.test() 为 false,nonNull.negate() 为 false,因为最后一个是 and,所以不需要判断 Predicate.isEqual("123"),最后得出 false || false 为 false。如果 and 之后还有 or 的话要接着判断。

Consumer

Consumer<T> 中 T 是传入参数的类型,没有返回值。源码中有 accept 和 andThen 方法。

@FunctionalInterface
public interface Consumer<T> {
    //执行方法
    void accept(T t);
    //先执行当前函数,再执行 after 函数
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

示例如下。

Consumer<Integer> consumer1 = integer -> System.out.println(integer + 1);
Consumer<Integer> consumer2 = integer -> System.out.println(integer + 2);
//先执行 consumer1,再执行 consumer2
consumer1.andThen(consumer2).accept(1);

执行后控制台依次打印 2 和 3。

Supplier

Supplier<T> 中 T 是返回值的类型,没有传入的参数。源码中只有 get 方法。

@FunctionalInterface
public interface Supplier<T> {
	//执行方法
    T get();
}

示例如下。

Supplier<LocalDate> supplier = LocalDate::now;
//返回当前日期
LocalDate localDate = supplier.get();
System.out.println(localDate);

控制台打印当前日期时间 2020-05-31。

总结

本文对 Java8 中的 lambda 做了简单了解,介绍了 5 种函数,想熟练使用还需要实践(第一次写博客,有不足还请指正)。

参考资料

深入浅出 Java 8 Lambda 表达式

Execution in the Kingdom of Nouns

函数式编程中的重要概念


原文链接:https://www.cnblogs.com/hligy/p/12996875.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:java 在线网络考试系统源码 springboot mybaits vue.js 前后分离

下一篇:基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、