4

I know how to pass in arguments to a method- you put the class/primitive name in the method header and substitute a value of that type when calling said method. Is it possible to pass in a series of statements to a method (in java), similarly to the way variables are passed in? For example, something such as:

repeat(5) {
    System.out.println("Hello");
}
...
private void repeat(int arg, {} statements) {
    for (int x = 0; x < arg; x++) {
        statements;
    }
}

The desired output here would be to print out "Hello" 5 times.

Obviously the syntax isn't correct, but would this be possible in any way?

RobotKarel314
  • 417
  • 3
  • 14

4 Answers4

5

Pass an object which has a function performing that series of statements.

Alexander Kulyakhtin
  • 47,782
  • 38
  • 107
  • 158
3

You pass an object with a method that has the statements you want to run.

An easy way to do this is implementing the Runnable interface with an anonymous class.

private void repeat(int times, Runnable action) {
    for (int x = 0; x < times; x++) {
        action.run();
    }
}

...

repeat(5, new Runnable(){
    void run(){
        System.out.println("Hello");
    }
});
Kevin Peña
  • 712
  • 3
  • 10
  • You might also mention that this could also be called with a lambda: `repeat(5, () -> System.out.println("Hello"));` without any changes to your repeat method. – Hulk Jun 21 '16 at 10:38
2

You have several options. Using Java 8 you can just pass in an interface:

public class Test {

public interface MyStatements {
    //one argument if needed
    public void execute(int arg1);
}

public static void main(String args[]) {
    // lambda
    MyStatements statements = a -> System.out.println(a);
    repeat(20, statements);

}

private static void repeat(int arg, MyStatements statements) {
    for (int x = 0; x < arg; x++) {
        statements.execute(x);
    }
}

}

You can also do this in Groovy

private static void repeat(int arg, Closure closure) {
    for (int x = 0; x < arg; x++) {
        closure(x)
    }
}

repeat(20, {myInt -> println(myInt)})
Chewy
  • 651
  • 6
  • 21
1

You can create an interface that has a standardized method. Say for instance the "Lambda" interface. That interface then would have a method called act() for example.

public interface Lambda{
    public void act();
}

now when you want to do this you can have a function called repeat

public static void repeat(int x, Lambda lambda){
    for(int y = 0;y<x;y++){
        lambda.act();
    {
}

and you would call that like this

public static void main(String args[]){
    repeat(5, new Lambda(){
           @Override
           public void act(){
                System.out.println("hello");
           });
}

Essentially what you are doing here is referred to as Overriding a parent's methods by using a child. The new Lambda() line creates new anonymous child of the Lambda interface -- See what anonymouse Classes are here.

Ryuzaki
  • 91
  • 6
  • No need to create a new interface for that - `Runnable` already exists and would be appropriate in this context. – Hulk Jun 21 '16 at 10:41
  • I understand that & i agree, However for the people reading the question in the future. I kinda wanted a simple explanation for how interfaces and anonymous classes worked. – Ryuzaki Jun 21 '16 at 17:25