内容简介:Java8回忆录 - Lambda
本文主要介绍 Java8
的 Lambda
表达式
基本语法
(parameters) -> expression (parameters) -> {statements;}
Apple
相关代码托管在 java8_demo
@Data @AllArgsConstructor @NoArgsConstructor public class Apple{ public static enum COLOR { GREEN, RED } public static final int HEAVY_WEIGHT = 200; private COLOR color; private Integer weight; }
实例
(String s) -> s.length() // 等价于 int f(String s){ return s.length(); } (Apple a) -> a.getWeight() > Apple.HEAVY_WEIGHT // 等价于 boolean f(Apple a){ return a.getWeight() > Apple.HEAVY_WEIGHT; } (int x, int y) -> { System.out.println("Result:"); Syetem.out.println(x+y; } // 等价于 void f(intx,inty){ System.out.println("Result:"); Syetem.out.println(x+y; } () -> 42 // 等价于 int f(){ return 42; } (Apple a1 , Apple a2) -> a1.getWeight() > a2.getWeight // 等价于 boolean f(Apple a1 , Apple a2){ return a1.getWeight() > a2.getWeight;}
函数式接口 + 函数描述符
函数式接口
-
定义:只定义了
一个抽象方法
(排除default
方法)的接口 -
用途:
Lambda
表达式允许直接以内联
的形式,为函数式接口的抽象方法提供实现
,并把整个表达式作为函数式接口的实例
函数描述符
-
定义:
函数式接口的抽象方法的签名
-
函数描述符
=函数式接口的抽象方法的签名
=Lambda表达式的签名
Lambda 出现的地方
-
赋值给一个变量(类型为
函数式接口
) -
传递给一个接受
函数式接口为参数的方法
自定义函数式接口
函数式接口
@FunctionalInterface public interface Change{ // 只有一个抽象方法 Integeraction(Integer param); }
函数描述符: Integer -> Integer
单元测试
private int localChange(intparam, Change change){ return change.action(param); } @Test public void multipyTest(){ // Lambda 能够赋值给一个函数式接口的变量(前提是函数式接口的抽象方法的签名 = Lambda 表达式的签名) Change multiply = param -> param * 3; assertEquals(15, localChange(5, multiply)); // Lambda 能够传递给一个接受函数式接口为参数的方法(前提是函数式接口的抽象方法的签名 = Lambda 表达式的签名) assertEquals(4, localChange(3, param -> param + 1)); }
常用内置函数式接口
函数式接口 | 函数描述符 |
---|---|
Predicate<T>
|
T -> boolean |
Consumer<T>
|
T -> void |
Supplier<T>
|
() -> T |
Function<T,R>
|
T -> R |
BiFunction<T,U,R>
|
(T,U) -> R |
BiPredicate<T,U>
|
(T,U) -> boolean |
BinaryOperator<T> extends BiFunction<T,T,T>
|
(T,T) -> T |
BiConsumer<T,U>
|
(T,U) -> void |
UnaryOperator<T> extends Function<T,T>
|
T -> T |
Predicate
定义
@FunctionalInterface public interface Predicate<T>{ boolean test(T t); }
函数描述符: T -> boolean
实例
private <T> List<T>predicate(List<T> list, Predicate<T> predicate){ List<T> result = new ArrayList<>(); for (T t : list) { if (predicate.test(t)) { result.add(t); } } return result; } @Test public void predicateTest(){ assertEquals(2, predicate(Arrays.asList("zhongmingmao", "", null), s -> null == s || s.isEmpty()).size()); }
Consumer
定义
@FunctionalInterface public interface Consumer<T>{ void accept(T t); }
函数描述符: T -> void
实例
private <T> void consume(List<T> list, Consumer<T> consumer){ for (T t : list) { consumer.accept(t); } } @Test public void consumerTest(){ consume(Arrays.asList(1, 2, 3), integer -> System.out.println(integer)); }
Supplier
定义
@FunctionalInterface public interface Supplier<T>{ Tget(); }
函数描述符: () -> T
实例
private <T> Tsupply(Supplier<T> supplier){ return supplier.get(); } @Test public void supplierTest(){ assertEquals(LocalDate.now(), supply(() -> LocalDate.now())); }
Function
定义
@FunctionalInterface public interface Function<T,R>{ Rapply(T t); }
函数描述符: T -> R
实例
private <T, R> Rfunction(T t, Function<T, R> func){ return func.apply(t); } @Test public void functionTest(){ assertEquals(Integer.valueOf(12), function(Integer.valueOf(4), integer -> integer * 3)); }
BiFunction
定义
@FunctionalInterface public interface BiFunction<T,U,R>{ Rapply(T t, U u); }
函数描述符: (T,U) -> R
实例
private <T, U, R> RbiFunction(T t, U u, BiFunction<T, U, R> biFunc){ return biFunc.apply(t, u); } @Test public void biFunctionTest(){ assertEquals("40", biFunction(4, "0", (integer, s) -> integer + s)); }
BiPredicate
定义
@FunctionalInterface public interface BiPredicate<T,U>{ boolean test(T t, U u); }
函数描述符: (T,U) -> boolean
实例
private <T, U> boolean biPredicate(T t, U u, BiPredicate<T, U> biPred){ return biPred.test(t, u); } @Test public void biPredicateTest(){ assertTrue(biPredicate(4, "zhognmingmao", (integer, s) -> null != s && s.length() > integer)); }
BinaryOperator
定义
@FunctionalInterface public interface BinaryOperator<T>extends BiFunction<T,T,T>{ }
函数描述符: (T,T) -> T
实例
private <T> TbinaryOperator(T t, BinaryOperator<T> bOp){ return bOp.apply(t, t); } @Test public void binaryOperatorTest(){ assertEquals(Integer.valueOf(16), binaryOperator(4, (integer, integer2) -> integer * integer2)); }
BiConsumer
定义
@FunctionalInterface public interface BiConsumer<T,U>{ void accept(T t, U u); }
函数描述符: (T,U) -> void
实例
private <T, U> void biConsumer(T t, U u, BiConsumer<T, U> bCon){ bCon.accept(t, u); } @Test public void biConsumerTest(){ biConsumer(4, "zhongmingmao", (integer, s) -> System.out.println(integer + s.length())); }
UnaryOperator
定义
@FunctionalInterface public interface UnaryOperator<T>extends Function<T,T>{ }
函数描述符: T -> T
实例
private <T> TunaryOperator(T t, UnaryOperator<T> uOp){ return uOp.apply(t); } @Test public void unaryOperatorTest(){ assertEquals("zhongmingmao" , unaryOperator("zhongming" , s -> s + "mao")); }
IntPredicate
-
IntPredicate
是Predicate<Integer>
的原始类型特化
,节省了自动装箱
和自动拆箱
的开销 -
类似函数式接口的还有
LongPredicate
、IntFunction<R>
等
定义
@FunctionalInterface public interface IntPredicate{ boolean test(intvalue); }
实例
@Test public void intPredicateTest(){ IntPredicate intPredicate = value -> value % 2 == 0; Predicate<Integer> integerPredicate = integer -> integer % 2 == 0; int max = 1 << 30; long p1 = System.currentTimeMillis(); for (int i = 0; i < max; i++) { intPredicate.test(i); } long p2 = System.currentTimeMillis(); for (int i = 0; i < max; i++) { integerPredicate.test(i); } long p3 = System.currentTimeMillis(); System.out.println((p3 - p2) / (p2 - p1 + 0.0)); // 本地结果在100~220之间 assertTrue((p3 - p2) > (p2 - p1)); }
类型检查
引用上面的例子进行分析
// 函数定义 private <T> List<T>predicate(List<T> list, Predicate<T> predicate){...} // 函数调用 predicate(Arrays.asList("zhongmingmao", "", null), s -> null == s || s.isEmpty()).size());
-
函数定义中形参为
Predicate<T> predicate
-
Predicate<T>
中的抽象函数的签名为boolean test(T t)
,因此Predicate<T>
的函数描述符
为T -> boolean
-
函数调用中
Lambda
的签名
为String -> boolean
与Predicate<T>
的函数描述符
匹配,类型检查通过
方法引用
方法引用
是 Lambda
的一种 快捷写法
(
语法糖
)
静态方法
-
Lambda:
(args) -> ClassName.staticMethod(args)
-
方法引用:
ClassName::staticMethod
Function<String, Integer> str2Integer = s -> Integer.parseInt(s); str2Integer = Integer::parseInt;
任意类型的实例方法
-
Lambda:
(arg0,rest) -> arg0.instanceMethod(rest)
(arg0
是ClassName
类型) -
方法引用:
ClassName::instanceMethod
BiPredicate<List<String>, String> contains = (strings, s) -> strings.contains(s); contains = List::contains;
现有对象的实例方法
-
Lambda:
(args) -> expr.instanceMethod(args)
-
方法引用:
expr::instanceMethod
List<String> list = Arrays.asList("a", "b", "A", "B"); Predicate<String> contain = s -> list.contains(s); contain = list::contains;
构造函数
Supplier<Apple> c1 = () -> new Apple(); c1 = Apple::new;// 默认构造函数 Apple apple = c1.get(); BiFunction<Apple.COLOR, Integer, Apple> c2 = (color, integer) -> new Apple(color, integer); c2 = Apple::new;// 2个参数构造函数 apple = c2.apply(Apple.COLOR.GREEN, Integer.valueOf(200));
复合Lambda
Comparator复合
@FunctionalInterface public interface Comparator<T>{ int compare(T o1, T o2); } // <T, U extends Comparable<? super U>> Comparator<T> comparing( // Function<? super T, ? extends U> keyExtractor) Comparator<Apple> comparator = Comparator.comparing(Apple::getWeight); // Apple -> Integer Comparator<Apple> reversedComparetor = comparator.reversed(); Comparator<Apple> linkedComparator = Comparator.comparing(Apple::getWeight).reversed() .thenComparing(Apple::getColor).reversed();
Predicate复合
Predicate<Apple> greenApple = apple -> Apple.COLOR.GREEN.equals(apple.getColor()); Predicate<Apple> notGreenApple = greenApple.negate(); Predicate<Apple> heavyApple = apple -> apple.getWeight() > Apple.HEAVY_WEIGHT; Predicate<Apple> greenAndHeavyApple = greenApple.and(heavyApple); Predicate<Apple> redApple = apple -> Apple.COLOR.RED.equals(apple.getColor()); Predicate<Apple> greenAndHeavyOrRedApple = greenAndHeavyApple.or(redApple); // 优先级从左至右,(red or green) and heavy Predicate<Apple> redOrGreenAndHeavyApple = redApple.or(greenApple).and(heavyApple);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 低成本“全栈”回忆录
- 一个 Java 对象的回忆录:垃圾回收
- 我的本科回忆录:从迷茫自卑到保送华科
- CSS :visited伪类选择器隐秘往事回忆录
- HBase 抗战总结:阿里巴巴 HBase 高可用 8 年抗战回忆录
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数据驱动设计
[美]罗谢尔·肯(RochelleKing)、[美]伊丽莎白F.邱吉尔(Elizabeth F Churchill)、Caitlin Tan / 傅婕 / 机械工业出版社 / 2018-8 / 69.00元
本书旨在帮你了解数据引导设计的基本原则,了解数据与设计流程整合的价值,避免常见的陷阱与误区。本书重点关注定量实验与A/B测试,因为我们发现,数据分析与设计实践在此鲜有交集,但相对的潜在价值与机会缺大。本书提供了一些关于在组织中开展数据实践的观点。通过阅读这本书,你将转变你的团队的工作方式,从数据中获得大收益。后希望你可以在衡量指标的选择、佳展示方式与展示时机、测试以及设计意图增强方面,自信地表达自......一起来看看 《数据驱动设计》 这本书的介绍吧!