Java8回忆录 - Lambda

栏目: 编程语言 · Java · 发布时间: 6年前

内容简介:Java8回忆录 - Lambda

本文主要介绍 Java8Lambda 表达式

基本语法

(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;}

函数式接口 + 函数描述符

函数式接口

  1. 定义:只定义了 一个抽象方法 (排除 default 方法)的接口
  2. 用途: Lambda 表达式允许直接以 内联 的形式, 为函数式接口的抽象方法提供实现 ,并把整个表达式作为 函数式接口的实例

函数描述符

  1. 定义: 函数式接口的抽象方法的签名
  2. 函数描述符 = 函数式接口的抽象方法的签名 = Lambda表达式的签名

Lambda 出现的地方

  1. 赋值给一个变量(类型为 函数式接口
  2. 传递给一个接受 函数式接口为参数的方法

自定义函数式接口

函数式接口

@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

  1. IntPredicatePredicate<Integer> 原始类型特化 ,节省了 自动装箱自动拆箱 的开销
  2. 类似函数式接口的还有 LongPredicateIntFunction<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());
  1. 函数定义中形参为 Predicate<T> predicate
  2. Predicate<T> 中的抽象函数的签名为 boolean test(T t) ,因此 Predicate<T>函数描述符T -> boolean
  3. 函数调用中 Lambda签名String -> booleanPredicate<T>函数描述符 匹配,类型检查通过

方法引用

方法引用Lambda 的一种 快捷写法 语法糖

静态方法

  1. Lambda: (args) -> ClassName.staticMethod(args)
  2. 方法引用: ClassName::staticMethod
Function<String, Integer> str2Integer = s -> Integer.parseInt(s);
str2Integer = Integer::parseInt;

任意类型的实例方法

  1. Lambda: (arg0,rest) -> arg0.instanceMethod(rest)arg0ClassName 类型)
  2. 方法引用: ClassName::instanceMethod
BiPredicate<List<String>, String> contains = (strings, s) -> strings.contains(s);
contains = List::contains;

现有对象的实例方法

  1. Lambda: (args) -> expr.instanceMethod(args)
  2. 方法引用: 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);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据驱动设计

数据驱动设计

[美]罗谢尔·肯(RochelleKing)、[美]伊丽莎白F.邱吉尔(Elizabeth F Churchill)、Caitlin Tan / 傅婕 / 机械工业出版社 / 2018-8 / 69.00元

本书旨在帮你了解数据引导设计的基本原则,了解数据与设计流程整合的价值,避免常见的陷阱与误区。本书重点关注定量实验与A/B测试,因为我们发现,数据分析与设计实践在此鲜有交集,但相对的潜在价值与机会缺大。本书提供了一些关于在组织中开展数据实践的观点。通过阅读这本书,你将转变你的团队的工作方式,从数据中获得大收益。后希望你可以在衡量指标的选择、佳展示方式与展示时机、测试以及设计意图增强方面,自信地表达自......一起来看看 《数据驱动设计》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具