【问题标题】:How can I chain functional calls in Java?如何在 Java 中链接函数调用?
【发布时间】:2020-01-07 13:07:06
【问题描述】:

我有两段相似的代码:

void task1() {
    init();
    while(someCondition) {
      doSomething();
    }
    shutdown();
  }
void task2() {
    while(someCondition) {
      init();
      doSomething();
      shutdown();
    }
  }

我想避免代码重复,我认为这可以通过使用函数式方法来完成。 我想将循环和 init/shutdown 调用放在单独的函数中,然后链接它们的调用(不是 Java 8 Function 接口,更多伪代码):

Function setup(Function f){
    init();
    f();
    shutdown();
}
Function loop(Function f){
    while(someCondition) {
      f();
    }
}

然后我想像这样链接这些:

void task1() {
   setup(loop(doSomething));
 }
void task2() {
    loop(setup(doSomething));
  }

我想到了 Java 的 Function 接口中的 compose/andThen,但它们不适合,因为它们只将一个函数的返回值交给下一个函数。有谁知道如何使用 Java 8 或其他方法来做到这一点?

【问题讨论】:

  • 为什么初始代码会困扰您?如果initdoSomethingshutdown是实际方法,则没有重复。
  • 你想多了。初始代码没有问题。
  • 我稍微缩短了代码,其中有一些重复。然而它并没有真正困扰我,我只是想提高我的 Java 技能。我认为可能有更好的方法来做到这一点,如果没有我对初始代码没问题。
  • 重复的代码块 -> 创建一个方法。 (不要把它当作信条,但你应该明白这一点)
  • 完全同意,我只是好奇这种方法是否适用于 Java

标签: java java-8 functional-programming


【解决方案1】:

您确实可以做到这一点。您需要Runnable,而不是Function,因为您的方法不接受任何参数并且不返回任何值。但是,如果您的方法具有不同的签名,则需要使用另一种类型。

public static void init() { ... }
public static void doSomething() { ... }
public static void shutdown() { ... }

public static Runnable setup(Runnable r) {
    return () -> {
        init();
        r.run();
        shutdown();
    };
}

public static Runnable loop(Runnable r) {
    return () -> {
        while (someCondition) {
            r.run();
        }
    };
}

// I used "Main" here because this in a class called Main. Replace "Main" with the name of your class
public static void task1() {
    setup(loop(Main::doSomething)).run();
}

public static void task2() {
    loop(setup(Main::doSomething)).run();
}

还应该注意的是,虽然在函数式程序员的眼中,第一个代码可能看起来“重复”,但对于 Java 程序员来说,第一个代码是非常好的。以这种方式重写它可能会让不习惯函数式风格的人更加困惑。

【讨论】:

  • 只是为了清楚起见 - 它不一定是Runnable。它必须是一个函数式接口,其方法不带参数也不返回任何内容 - Runnable 恰好是一个。
  • 这正是我想要的,谢谢:) 我完全知道这不一定是最好的风格,我只是好奇如何在 Java 中做到这一点
  • @Amongalen 是的,这很清楚,但他们没有像使用 Callable 和 Supplier 那样在 Java 8 中引入新接口,对吧?
  • @MaxZofal 我认为您的意思是java.util.function package - 有多种变体,但没有“null to null”选项。 Callable 是别的东西,不是那个包的一部分。
猜你喜欢
  • 2022-01-16
  • 1970-01-01
  • 2017-10-14
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
相关资源
最近更新 更多