How can I chain functional calls in Java?

Max Zofal :

I have two similar pieces of Code:

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

I would like to avoid code duplication and I thought this could be done by using a functional approach. I want to put the loop and the init/shutdown call in seperate functions and then chain their calls (not the Java 8 Function interface, more pseudocode):

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

Then I want to chain these like this:

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

I thought of compose/andThen in Java's Function interface but they are not suitable because they only hand on the return value of one function to the next one. Does anyone have an idea how to do this with Java 8 or with a different approach?

Sweeper :

You can indeed do this. You need Runnable, not Function, since your methods accept no parameters and return no value. If your methods have a different signature though, you need to use another type.

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

It should also be noted that although to a functional programmer's eyes, the first code might look "duplicated", to Java programmers, the first code is very fine as it is. Rewriting it this way might be more confusing to people who are not used to the functional style.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=414564&siteId=1