5

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?

5
  • 4
    why does the initial code bother you? If init, doSomething and shutdown are actual methods, there is no duplication. Commented Jan 7, 2020 at 13:11
  • 3
    You are overthinking this. There's nothing wrong with the initial code. Commented Jan 7, 2020 at 13:12
  • I shortend the code a bit, there is some duplication in it. However it does not really bother me, I am just trying to improve my Java skills. I thought there could there could be a nicer way to do it, if there isn't I'm fine with the initial code. Commented Jan 7, 2020 at 13:24
  • duplicated block of code -> make a method. (Don't take that as a creed but you should get the point) Commented Jan 7, 2020 at 13:26
  • absolutely agree, I was just curious if this approach works in Java Commented Jan 7, 2020 at 13:30

1 Answer 1

10

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Just for the clarity - it doesn't have to be Runnable. It has to be a functional interface with a method that takes no parameters and returns nothing - Runnable just happend to be one.
That is exactly what I wanted,Thank you:) I'm totally aware this is not necessarily the best style, I was just curious how it could be done in Java
@Amongalen yes that's clear but they didn't introduce a new interface in Java 8 for that purpose like they did with Callable and Supplier right?
@MaxZofal I think what you've meant is java.util.function package - there are multiple variants but no "null to null" option. Callable is something else tho, not part of that package.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.