In Java 8 and above you can create a List of Functional Interfaces to store the methods, as the following example shows:
// Create a list of Consumer
List<Consumer<String>> methodList= new ArrayList<>();
// Store the methods in the list
methodList.add(p -> method1(p));
methodList.add(p -> method2(p));
methodList.add(p -> method3(p));
methodList.forEach(f -> f.accept("Hello"));
Functions with no arguments you can use Runnable:
List<Runnable> methods = new ArrayList<>();
methods.add(() -> method1());
methods.add(() -> method2());
methods.add(() -> method3());
methods.forEach(f -> f.run());
Answer from Rodrigo Eggea on Stack Overflowcollections - How to create list filled with methods in Java and iterate over it (using methods) - Stack Overflow
How do I create a List of functions in Java? - Stack Overflow
How to create a Java Function list? - Stack Overflow
Multiple ways to declare a list(JAVA)?
Videos
In Java 8 and above you can create a List of Functional Interfaces to store the methods, as the following example shows:
// Create a list of Consumer
List<Consumer<String>> methodList= new ArrayList<>();
// Store the methods in the list
methodList.add(p -> method1(p));
methodList.add(p -> method2(p));
methodList.add(p -> method3(p));
methodList.forEach(f -> f.accept("Hello"));
Functions with no arguments you can use Runnable:
List<Runnable> methods = new ArrayList<>();
methods.add(() -> method1());
methods.add(() -> method2());
methods.add(() -> method3());
methods.forEach(f -> f.run());
In Java, you can do this with reflection by making a list of Method objects. However, an easier way is to define an interface for objects that have a method that takes an Object argument:
public interface MethodRunner {
public void run(Object arg);
}
List<MethodRunner> a = new ArrayList<>();
a.add(new MethodRunner() {
@Override
public void run(Object arg) {
myCustomMethod1(arg);
}
});
a.add(new MethodRunner() {
@Override
public void run(Object arg) {
myCustomMethod2(arg);
}
});
Object o = new Object();
for (MethodRunner mr : a) {
mr.run(o);
}
First, create a functional interface that represents the common signature of all the functions. Note: there may be an interface from the java.util.function package that can be used to represent the signature, so it may not be necessary to create a new interface.
// for example
@FunctionalInterface
interface MyFunction {
int f(int a, int b); // this must match the signature of each function
}
Then, create a List of that type.
List<MyFunction> functions = List.of(this::myFunction, MyClass::someOtherFunction);
You have to help Java a little for this one:
var myListOfFunctions = List.<Function<String,Integer>> of(this::myFunction, MyClass::someOtherFunction);
This would generate a List<Function<String, Integer>>.
These all work, but I'm confused as to why they're different:
List temp1 = new ArrayList<Integer>();
List temp2 = new ArrayList<>();
List<Integer> temp3 = new ArrayList<>();
List<Integer> temp4 = new ArrayList<Integer>();
temp1.add(1);
temp1.add(2);
temp2.add(3);
temp2.add(4);
temp3.add(5);
temp3.add(6);
temp4.add(7);
temp4.add(8);
System.out.println(temp1); //[1, 2]
System.out.println(temp2); //[3, 4]
System.out.println(temp3); //[5, 6]
System.out.println(temp4); //[7, 8]I was always under the impression that temp4 was the required way, but these all run and work. When should I use each or is it bad practice to not use temp 4?
In Java, this is the best you can hope for. For each new function, you must make an additional change to ensure that it gets called. While you could pass an array of Functions to prevent setting up each individual call, you still need to alter the array with each successive function created, so it is ultimately no better.
Though if you're like me, you may want to categorize these functions so that you can have a single comprehensive list. While it doesn't reduce the amount of changes you'll need to make to the code, this way I find is more organized.
public enum TestFunctions {
BUBBLE_SORT(SortingAlgorithms::bubbleSort),
QUICK_SORT(SortingAlgorithms::quickSort),
MERGE_SORT(SortingAlgorithms::mergeSort),
INSERTION_SORT(SortingAlgorithms::insertionSort);
UnaryOperator<Integer[]> function;
private TestFunctions(UnaryOperator<Integer[]> function) {
this.function = function;
}
public Integer[] call(Integer[] input) {
return this.function.apply(input);
}
}
Like this, your code can separate the function from where it's implemented. You'd still need to add the new function here, but there's no getting around this unless you used reflection. Though you could use reflection, I would strongly discourage you from doing so. My experience is that it tends to create more problems than it solves in the long run.
Good luck!
If you want to create a list of functions, that is very easy. You literally just need to create a List of Functions. Example:
import java.util.List;
import java.util.function.Function;
class Test {
private static List<Function<int[], int[]>> functions = List.of(
a -> new int[] { a[0] + a[1] },
a -> new int[] { a[0] - a[1] }
);
public static void main(String[] args) {
for (var f : functions) {
System.out.println(f.apply(new int[] { 1, 2 })[0]);
}
}
}
// 3
// -1