Java's equivalents of Func and Action

Java

Java Problem Overview


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;
}

Java Solutions


Solution 1 - Java

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);
  }
}

Solution 2 - Java

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... 
      }
});

Solution 3 - Java

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.

Solution 4 - Java

Solution 5 - Java

You can use java.util.Function like this

Function<Employee, String> f0 = (e) -> e.toString();

But if you are to use it with more than one argument(as C# Func is does), then you have define your version of FunctionalInterface as follows

@FunctionalInterface
public interface Func2Args<T, T1, R> {
    R apply(T t, T1 t1);
}

@FunctionalInterface
public interface Func3Args<T,T1,T2,R> {
    R apply(T t, T1 t1, T2 t2);
}

Then you can use with variable no of arguments

Func2Args<Employee,Employee,String> f2 = (e, e2) -> e.toString() + 
e2.toString();

Func3Args<Employee,Employee,Employee,String> f3 = (e, e2, e3) -> 
e.toString() + e2.toString() + e3.toString();

Solution 6 - Java

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.

Solution 7 - Java

Java doesn't have the concept of delegates. For a workaround approach, please see A Java Programmer Looks at C# Delegates:

> 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.

Solution 8 - Java

For older versions than Java 8

For method callbacks in C# which I used like this:

public void MyMethod(string par1, string par2, Action<int> callback, Action<int, string> callback2)
{
    //Async Code 
        callback.invoke(1);
        callback2.invoke(4, "str");
}

and calling it:

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:

package com.example.app.interfaces;
public interface MyInterface<T> {
    void makeDo(T obj);
    void makeAnotherDo();
}

Solution 9 - Java

Since Java 8, Func and Action can be achieved through Functional Interface and Lambda Expression.

Functional Interface is an interface that has only one abstract method.

@FunctionalInterface
interface Drawable {
    void Draw();
}

@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.

(This is summarized from https://www.byteinthesky.com/tutorials/func-and-action-equivalent-in-java/)

Solution 10 - Java

If you're coming from a C# background (like I do) and looking for:

public delegate TResult Func<in T1,in T2,out TResult>(T1 arg1, T2 arg2);

Take a look at:

public interface BiFunction<T, U, R>

Solution 11 - Java

This is my implement with the lack of Action multiple params typed generic interface.

package x.y.delegate;

public class IAction {
    public interface _0 { void execute(); }
    public interface _1<T> { void execute(T p); }
    public interface _2<T1, T2> { void execute(T1 p1, T2 p2); }
    public interface _3<T1, T2, T3> { void execute(T1 p1, T2 p2, T3 p3); }
    public interface _4<T1, T2, T3, T4> { void execute(T1 p1, T2 p2, T3 p3, T4 p4); }
    public interface _5<T1, T2, T3, T4, T5> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5); }
    public interface _6<T1, T2, T3, T4, T5, T6> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6); }
    public interface _7<T1, T2, T3, T4, T5, T6, T7> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7); }
    public interface _8<T1, T2, T3, T4, T5, T6, T7, T8> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8); }
    public interface _9<T1, T2, T3, T4, T5, T6, T7, T8, T9> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9); }
    public interface _10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10); }
    public interface _11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11); }
    public interface _12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12); }
    public interface _13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13); }
    public interface _14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14); }
    public interface _15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14, T15 p15); }
    public interface _16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14, T15 p15, T16 p16); }
}

class DoSomething {
    public void doSm(IAction._1 ack, IAction._2 ack2) {

    }
}

Or you can find my lib which include definition for Action, Func, Predicate and Tuple at this link: https://github.com/ThinhVu/javaext or https://jitpack.io/#ThinhVu/javaext/1.0.0

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionripper234View Question on Stackoverflow
Solution 1 - JavaRichard CookView Answer on Stackoverflow
Solution 2 - JavaGregory MostizkyView Answer on Stackoverflow
Solution 3 - JavaAleksandr DubinskyView Answer on Stackoverflow
Solution 4 - JavaTim SchrubenView Answer on Stackoverflow
Solution 5 - Javauser2739602View Answer on Stackoverflow
Solution 6 - JavaAgileJonView Answer on Stackoverflow
Solution 7 - JavaAndrew HareView Answer on Stackoverflow
Solution 8 - JavaPierreView Answer on Stackoverflow
Solution 9 - JavaharypsView Answer on Stackoverflow
Solution 10 - JavaRenato HeebView Answer on Stackoverflow
Solution 11 - JavaThinh VuView Answer on Stackoverflow