如何在Java中链接函数调用? - java

我有两段相似的代码:

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或其他方法实现此目的?

参考方案

您确实可以做到这一点。您需要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程序员来说,第一个代码实际上是非常好的。用这种方式重写它可能会使那些不习惯功能样式的人感到困惑。

Java:函数式编程中线程之间的状态共享 - java

我的问题是该问题的更具体实例:Functional programming: state vs. reassignment我是FP的新手,正尝试通过Java理解它。我有以下类,其对象在多个线程之间共享:public class Bank { private double[] accounts = new double[1000]; public synchr…

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java DefaultSslContextFactory密钥库动态更新 - java

我有一个使用org.restlet.engine.ssl.DefaultSslContextFactory的现有应用程序和一个在服务器启动时加载的密钥库文件。我有另一个应用程序,该应用程序创建必须添加的证书服务器运行时动态地更新到密钥库文件。为此,我在代码中创建了证书和私钥,然后将其写入到目录。该目录由bash脚本监视,该脚本检查是否有新文件,如果出现,它将…