Search code examples
javalambdarunnablefunctional-interface

Parametrise a Runnable object at runtime


I have a Runnable task (doSomething) that I need to parametrise depending on who calls run().

    Class SomeClass {
    
        Public void foo(ScheduledExecutorService execService, ){
            ...
            Runnable doSomething = () -> {
                /*Code that I DON’T want to duplicate*/
                ...
                /* small piece of code that I need to parametrise */
            };
            ...
        
            // after someDelayInSeconds doSomething.run() will be called
            execService.schedule(doSomething, someDelayInSeconds, TimeUnit.SECONDS); 

            // this might or might not call doSomething.run()
            bar(doSomething); 
    
            ...
        
        }

        private void bar(Runnable doSomething){

           ...
           if(/* some conditions are met */)
              doSomething.run();
           ...
        }
    }

So far the only alternative I have is to transform the anonymous class into a named class and create two objects with the required parameters.

Would there be a more elegant way?


Solution

  • I suggest you change doSomething to a Consumer that accepts your parameters:

    public void foo(ScheduledExecutorService execService) {
        Consumer<YourParams> doSomething = (params) -> {
            /*Code that I DON’T want to duplicate*/
            /* small piece of code that I need to parametrise */
            // use params
        };
    
        // after someDelayInSeconds doSomething.run() will be called
        YourParams asyncParams = /* parameters for async execution */;
        execService.schedule(() -> doSomething.accept(asyncParams), someDelayInSeconds, TimeUnit.SECONDS);
    
        // this might or might not call doSomething.run()
        bar(doSomething);
    
    }
    
    private void bar(Consumer<YourParams> doSomething) {
        if (/* some conditions are met */) {doSomething.accept(otherParams);}
    }
    

    In the scheduled execution you then transform doSomething into a Runnable by passing the default parameters for asynchronous execution, while in bar() you pass the alternative parameters of your choice directly.