Java中的TriFunction接口

2023/06/11

1. 概述

在本文中,我们将定义一个TriFunction函数式接口,它表示接收三个参数并计算结果的函数。稍后,我们还将看到一个使用Vavr库的内置Function3的示例。

2. 创建我们自己的TriFunction接口

从版本8开始,Java定义了BiFunction函数式接口。它表示接收两个参数并计算其结果的函数。为了允许函数组合,它还提供了一个andThen()方法,该方法将另一个Function应用于BiFunction的结果。

类似地,我们将定义我们的TriFunction接口并为其提供andThen()方法

@FunctionalInterface
public interface TriFunction<T, U, V, R> {

    R apply(T t, U u, V v);

    default <K> TriFunction<T, U, V, K> andThen(Function<? super R, ? extends K> after) {
        Objects.requireNonNull(after);
        return (T t, U u, V v) -> after.apply(apply(t, u, v));
    }
}

让我们看看如何使用这个接口。我们将定义一个接收三个Integer的函数,将前两个操作数相乘,然后相加最后一个操作数:

static TriFunction<Integer, Integer, Integer, Integer> multiplyThenAdd = (x, y, z) -> x * y + z;

请注意,只有当前两个操作数的乘积低于Integer最大值时,此方法的结果才是准确的。

例如,我们可以使用andThen()方法来定义一个TriFunction:

  • 首先,将multiplyThenAdd()应用于参数
  • 然后,应用一个Function,该函数将计算整数的欧几里得除以10的商应用于上一步的结果
static TriFunction<Integer, Integer, Integer, Integer> multiplyThenAddThenDivideByTen = multiplyThenAdd.andThen(x -> x / 10);

现在,我们可以编写一些快速测试来检查我们的TriFunction是否按预期运行:

@Test
void whenMultiplyThenAdd_ThenReturnsCorrectResult() {
    assertEquals(25, multiplyThenAdd.apply(2, 10, 5));
}

@Test
void whenMultiplyThenAddThenDivideByTen_ThenReturnsCorrectResult() {
    assertEquals(2, multiplyThenAddThenDivideByTen.apply(2, 10, 5));
}

最后一点,TriFunction的操作数可以是多种类型。例如,我们可以定义一个TriFunction,它根据布尔条件将Integer转换为String或返回另一个给定的String:

static TriFunction<Integer, String, Boolean, String> convertIntegerOrReturnStringDependingOnCondition = (myInt, myStr, myBool) -> {
    if (Boolean.TRUE.equals(myBool)) {
        return myInt != null ? myInt.toString() : "";
    } else {
        return myStr;
    }
};

3. 使用Vavr的Function3

Vavr库已经定义了一个具有我们想要的行为的Function3接口。首先,让我们将Vavr依赖项添加到我们的项目中:

<dependency>
    <groupId>io.vavr</groupId>
    <artifactId>vavr</artifactId>
    <version>0.10.4</version>
</dependency>

我们现在可以用它重新定义multiplyThenAdd()和multiplyThenAddThenDivideByTen()方法:

static Function3<Integer, Integer, Integer, Integer> multiplyThenAdd = (x, y, z) -> x * y + z;

static Function3<Integer, Integer, Integer, Integer> multiplyThenAddThenDivideByTen = multiplyThenAdd.andThen(x -> x / 10);

如果我们需要定义最多有8个参数的函数,使用Vavr是一个不错的选择。Function4、Function5、…Function8确实已经在库中定义了。

4. 总结

在本教程中,我们为接收3个参数的函数实现了自己的函数式接口。我们还强调了Vavr库包含此类函数的实现。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章