JAVA8 Lambda表达式
2020-05-31 16:01:39来源:博客园 阅读 ()
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
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- java8 stream的分组功能,具体时候是真的好用 2020-06-10
- 学习笔记之Lambda表达式 2020-06-05
- Kotlin与java8的SAM转换对比 2020-06-03
- JAVA8 Stream流 2020-06-02
- Lambda表达式用法大比较: Scala和Java 8 2020-05-26
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash