This is a thing that I’m sure a lot of Java programmers have come with an implementation for, but no minimal examples were easy to be found when I looked for it. And it was fun to code, too, so I’ll share it!
Many many times I find myself wanting to declare a simple function to be executed on all items in a list, much like I do in Python with lambdas. What I usually do is just write a separate method if I find myself doing this same thing several times, and call that method all over. This is boring, though!
With lambda functions I find this task a little less boring and, most of all, I can use the same scheme wherever I need it and it speeds up my work since my brain seems to enjoy this process much better..
This is the LambdaFunction
interface:
/**
* A function to be executed on all items in a list.
*
* <p>
* This is a verbose Java equivalent of lambda functions; it's verbose
* because you must declare a (private anonymous) class to define the lamba
* function.
*
* <p>
* This is how you would use it:
*
* <blockquote>
*
* <pre>
* List<MyClass> myList = Arrays.asList(new MyClass("one"), new MyClass("two"));
* Utils.executeAll(myList, new LambdaFunction<MyClass>() {
* public void execute(MyClass item) {
* // call one of MyClass methods
* item.foo();
* }
* }
* </pre>;
*
* </blockquote>; Where of course the {@link LambdaFunction} can be stored to
* be reused several times.
*
* @author mb
*
* @param <T>
* the type of elements in the list on which the lambda function
* must be executed
* @see Utils#callOnAll(List, LambdaFunction)
* @see Utils#callOnAll(Object[], LambdaFunction)
*/
public static interface LambdaFunction<T> {
/**
* The function called on all items in the list.
*
* @param item
* the item onto which the function must be called
*/
public void execute(T item);
}
(The interface is static just because in my code it’s in the same file as the Utils class, but you can put it in a separate file if you want).
As the javadoc explains, you use it in combination with the Utils.callOnAll()
method. Here are the two flavors:
public final class Utils {
/**
* Calls the argument lambda <tt>function</tt> on all items in the argument
* <tt>list</tt>.
*
* @param <T>
* the type of elements in the list
* @param list
* the list onto which the lambda function must be executed
* @param function
* the function to be executed on all items in the list
* @see LambdaFunction
*/
public static <T> void callOnAll(List<T> list, LambdaFunction<T> function) {
for (T item : list) {
function.execute(item);
}
}
/**
* Calls the argument lambda <tt>function</tt> on all items in the argument
* array.
*
* @param <T>
* the type of elements in the list
* @param items
* the items onto which the lambda function must be executed
* @param function
* the function to be executed on all items in the list
* @see LambdaFunction
*/
public static <T> void callOnAll(T[] items, LambdaFunction<T> function) {
for (T item : items) {
function.execute(item);
}
}
}
And this is an example of how I use it:
private static final LambdaFunction<TouchHandler> HANDLER_ENABLER = new LambdaFunction<TouchHandler>() {
@Override
public void execute(TouchHandler item) {
item.setEnabled(true);
}
};
Utils.callOnAll(handlers, HANDLER_ENABLER);
Yes, I could have just added a private void enableHandlers(boolean areEnabled)
method in this case, but I prefer to pollute my classes with as few private
utility methods as possible; private fields are hidden by Eclipse, so I never even pay attention to them. Plus, if I didn’t need to call HANDLER_ENABLER
several times I could have had a true(r) lambda function:
Utils.callOnAll(handlers, new LambdaFunction<TouchHandler>() {
@Override
public void execute(TouchHandler item) {
item.setEnabled(true);
}
});
Was it simple to implement? Yup. Is it less readable? Not really. Do I love using it? Definitely! 😀