设为首页 加入收藏

TOP

Java 函数式编程「二」
2023-07-25 21:33:47 】 浏览:14
Tags:Java

上回,聊聊函子 functor

functor 是一个容器。该容器的 value 属性指向被包裹的数据;该容器的 map 方法对容器进行映射变换。

以下代码实现一个最普通的 functor,称之为 Just, 根据 map 的传参 fnvalue 进行变换:

class Just<T> {
  private final T value;

  private Just(T value) {
    this.value = value;
  }

  public static <T> Just<T> of(T value) {
    return new Just<>(value);
  }

  public <R> Just<R> map(Function<T, R> fn) {
    return of(fn.apply(this.value));
  }

  public T flat() {
    return this.value;
  }
}

map 会继续返回 functor,因此可以链式调用:

public static void main(String[] args) {
  System.out.println(
    Just.of(1)
      .map(a -> a + 2)
      .map(a -> a * a)
      .flat()
  );
}

将数据用容器 functor 包装,通过唯一的 map 方法对数据进行变换,使得我们很容易封装类似切面的逻辑。例如:将判空的逻辑封装到 map 中,得到函子 Maybe

class Maybe<T> {
  public static final Maybe<?> EMPTY = new Maybe(null);

  private final T value;

  private Maybe(T value) {
    this.value = value;
  }

  public static <T> Maybe<T> of(T value) {
    if (value == null) {
      return (Maybe<T>) EMPTY;
    } else {
      return new Maybe<>(value);
    }
  }

  public <R> Maybe<R> map(Function<T, R> fn) {
    if (this == EMPTY) {
      return (Maybe<R>) EMPTY;
    } else {
      return of(fn.apply(this.value));
    }
  }

  public T orElse(T v) {
    if (this == EMPTY) {
      return v;
    } else {
      return this.value;
    }
  }
}

由于 Maybemap 中包含判空的逻辑,因此调用 map 不用考虑空值,只需要在最后考虑空值。它使得我们更多地关注正常数据流。

class Person {
  public String name;
  public Car car;
}

class Car {
  public String label;
}

public class Test {
  public static void main(String[] args) {
    Person apolis = new Person();
    apolis.name = "apolis";

    System.out.println(
      Maybe.of(apolis)
        .map(p -> p.car)
        .map(c -> c.label)
        .orElse("no car")
    );
  }
}

Maybe 函子在 java 中对应的实现是类 Optional

如果你能找出下面代码里的问题,就证明你已经掌握了 Optional 的用法:

// 问题代码
String name = "";
Optional<String> optional = result.getPrimaryMap()
  .values().stream().findFirst();
if (optional.isPresent()) {
  name = optional.get();
}

java 有了 Optional,可以表达更多的信息。例如:一个方法的返回值类型是 Optional<XXX>,会告诉调用者,该方法有可能返回空值。如果我们能统一规范:会返回空值的方法都改为返回 Optional,将使 api 更易用。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇java笔记(5)(this,super,overrid.. 下一篇项目实战:并发下保证接口的幂等性

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目