Java's equivalents of Func and Action
What are Java's equivalents of Func and Action?
I mean, instead of writing this on my own:
public interface Func<TInput, TResult>
{
TResult call(TInput target) throws Exception;
}
public interface Action<T>
{
void call(T target) throws Exception;
}
In Java 8, the equivalents are the java.util.function.Function<T, R>
and java.util.function.Consumer<T>
interfaces respectively. Similarly, java.util.function.Predicate<T>
is equivalent to System.Predicate<T>
. As mentioned elsewhere, these are interfaces instead of delegates.
Related aside: I'm currently leaning heavily on the following utility class to do LINQ-like extension method stuff:
abstract class IterableUtil {
public static <T> Iterable<T> where(Iterable<T> items, Predicate<T> predicate) {
ArrayList<T> result = new ArrayList<T>();
for (T item : items) {
if (predicate.test(item)) {
result.add(item);
}
}
return result;
}
public static <T, R> Iterable<R> select(Iterable<T> items, Function<T, R> func) {
ArrayList<R> result = new ArrayList<R>();
for (T item : items) {
result.add(func.apply(item));
}
return result;
}
}
Unlike System.Linq.Enumerable.Where<TSource>
and System.Linq.Enumerable.Select<TSource, TResult>
the LINQ-like methods I present here are not lazy and fully traverse the source collections before returning the result collections to the caller. Still, I find them useful for purely syntactic purposes and could be made lazy if necessary. Given
class Widget {
public String name() { /* ... */ }
}
One can do the following:
List<Widget> widgets = /* ... */;
Iterable<Widget> filteredWidgets = IterableUtil.where(widgets, w -> w.name().startsWith("some-prefix"));
Which I prefer to the following:
List<Widget> widgets = /* ... */;
List<Widget> filteredWidgets = new ArrayList<Widget>();
for (Widget w : widgets) {
if (w.name().startsWith("some-prefix")) {
filteredWidgets.add(w);
}
}
Callable interface is similar to Func.
Runnable interface is similar to Action.
In general, Java uses anonymous inner classes as a replacement for C# delegates. For example this is how you add code to react to button press in GUI:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
}
});
The elegance of the overloaded Func delegates (besides the delegate vs anonymous class issue) is that they support from 0 to 16 arguments (Func<TResult>
, Func<T, TResult>
, Func<T1, T2, TResult>
, etc.)
Unfortunately, this is impossible in Java because of type erasure. Classes cannot differ by generic type parameters alone.
Java 8 now brings in a zoo of names like BiConsumer
for Action<T, T2>
and, because Java does not allow primitive type arguments, BiIntConsumer
. The "zoo", though, is not very big, and I am not aware of a library that expands it. There was a wonderful proposal for function type literals like (int, int) => void
but it was not adopted.
For Func<T>
use: java.util.function.Supplier
http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html