聚飞

代码改变世界

Menu
  • Home
  • Python
  • Java
  • Go
  • PHP
  • C++
  • .NET
  • JavaScript
  • Vue
  • Andriod
  • IOS
  • Linux
Menu

Java 函数式编程「二」

2022年11月20日 apolis

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

接上回,聊聊函子 functor。

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

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

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

由于 Maybe 的 map 中包含判空的逻辑,因此调用 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 更易用。

来源:原文

Category: Java

搜索

随机文章推荐

  • Python数据分析–Numpy常用函数介绍(6)–Numpy中与股票成交量有关的计算
  • 不安装运行时运行 .NET 程序
  • 介绍一下sourcemap
  • GBase 8t索引
  • 【SIM】MCC(移动国家码)和 MNC(移动网络码)

最新文章推荐

  • 离线安装rpm包以及自建yum仓库
  • Mybatis的parameterType造成线程阻塞问题分析
  • 【python基础】循环语句-continue关键字
  • Java中的变量你了解吗?
  • Ubuntu22.04安装低版本MySQL5.7
© 2023 聚飞 | Sitemap