There really are no equivalents for those. You can create anonymous inner classes in Java, but there tends to be specific interfaces rather than such generic ones like Func and Action.
While C# has a set of capabilities
similar to Java, it has added several
new and interesting features.
Delegation is the ability to treat a
method as a first-class object. A C#
delegate is used where Java developers
would use an interface with a single
method. In this article, the use of
delegates in C# is discussed, and code
is presented for a Java Delegate
object that can perform a similar
function. Download the source code
here.
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.
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() { /* ... */ }
}
utils.MyMethod("par1", "par2", (i) =>
{
//cb result
}, (i, str) =>
{
//cb2 result
});
I have made small abstract classes in Java
package com.example.app.callbacks;
public abstract class Callback1<T> {
public void invoke(T obj) {}
}
package com.example.app.callbacks;
public abstract class Callback2<T, T2> {
public void invoke(T obj, T2 obj2) {}
}
package com.example.app.callbacks;
public abstract class Callback3<T, T2, T3> {
public void invoke(T obj, T2 obj2, T3 obj3) {}
}
...ETC
Java Method looks like:
public void myMethod(String par1, String par2, final Callback1<int> callback, final Callback2<int, String> callback2) {
//Async Code
callback.invoke(1);
callback2.invoke(4, "str");
}
Now when calling it in Java:
utils.myMethod("par1", "par2", new Callback<int>() {
@Override
public void invoke(int obj) {
super.invoke(obj);
//cb result
}
}, new Callback2<int, String>() {
@Override
public void invoke(int obj, String obj2) {
super.invoke(obj, obj2);
//cb2 result
}
});
This works also by passing/setting your callbacks to the classes in which you want to call them, the same method can be used to create Interfaces as well:
@FunctionalInterface attribute is optional. Meanwhile, Lambda Expression concept are the same for C# and Java.
Below Java and C# code are equivalent:
class App
{
public static void Main(string[] args)
{
Action action = () => { Console.WriteLine("Printing from App class"); };
action();
}
}
@FunctionalInterface
interface Drawable {
void Draw();
}
public class App {
public static void main(String[] args) throws Exception {
Drawable drawable = ()->System.out.println("Printing from App class");
drawable.Draw();
}
}
In Java, Func and Action are replaced with Functional Interface.
With this kind of interface, Java doesn't need specifically to have Func and Action delegate type because we can create any interface that satisfy Func and Action (be its parameters and return type). Consequently, the code in Java is a little more verbose than C# version.