Java's equivalents of Func and Action
Asked Answered
T

11

100

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;
}
Temporary answered 26/7, 2009 at 12:14 Comment(1)
Also see #7297106Fixative
E
119

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);
  }
}
Erring answered 31/3, 2014 at 4:24 Comment(3)
We really need to up vote this answer as this question is the current #1 search result for "Java equivalent of action" and it's now 2015 so the Java 8 stuff is way better than what Java had before and nearly mimics .net's stuff at this point.Picture
I think you meant Iterable<Widget> filteredWidgets = IterableUtil.where(widgets, w -> w.name().startsWith("some-prefix"));Squish
In addition of Function<T, R> and Consumer<T>, you can find the full set of common functional interfaces that Java provides here.Riesman
L
41

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... 
      }
});
Lucilucia answered 26/7, 2009 at 12:28 Comment(1)
What distinguishes Func from Callable, is that there are generic overloads for up to 16 arguments (Func<TResult>, Func<T, TResult>, Func<T1, T2, TResult>, etc.). OTOH, Callable takes no arguments. Moreover, it is impossible to implement C#'s overloads because of type erasure in generics.Loar
L
9

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.

Loar answered 14/4, 2013 at 11:40 Comment(2)
Interestingly, at the CLR level classes which differ only by the number of generic parameters do have different names. Func`1 etc. It's just C# that maps those to the same name.Adamson
@Adamson Ahh, very interesting. Too bad Java did not do it this way too. Btw, Java 8 now brings in a zoo of names like BiConsumer for Action<T, T2> and, because Java does not allow primitive type parameters, BiIntConsumer. There was a proposal for function type literals like (int, int) => void but it was not adopted.Loar
P
6

For Func<T> use: java.util.function.Supplier http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html

Public answered 29/11, 2016 at 20:3 Comment(7)
Supplier would be equivalent to Func<T> (as opposed to Func<T1, T2>) not Action. An Action accepts no arguments and returns no result. (Other versions of Action accept various numbers of arguments and return no result.)Cornfield
Yes you are right, my mistake. I ran into this post because I was looking for the Func<T> for Java and mistakenly remembered it as Action<T>. OopsPublic
The answer was helpful for me anyway. Does java also have something like Action<>: 0 inputs, 0 outputs. At best with .andThen(...) functionality.Duprey
I'm not aware of anything provided by the Java framework that is like Action<> with 0 inputs and 0 outputs. But remeber, in Java these are just interfaces. So, you can create your own to use.Public
There is Runnable for Action<>, although it's not quite as pretty to use as the new Java 8 functional stuff.Housetop
@MarkKCowan, I guess you could use Runnable, but that is more for multi threading. Plus IMHO I view Java 8 functional/lambda stuff, as a thinly veiled lie. In other languages I do not need to define an interface to create a lambda.Public
Why Supplier and not java.util.concurrent.Callable<T> or java.util.function.Function<T, R> ?Laborious
H
5

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();
Harryharsh answered 13/3, 2019 at 9:12 Comment(0)
L
3

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.

Lumpkin answered 26/7, 2009 at 12:17 Comment(0)
S
2

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.

Suspensor answered 26/7, 2009 at 12:18 Comment(0)
J
1

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();
}
Jalap answered 27/6, 2019 at 16:41 Comment(0)
C
1

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/)

Chromolithography answered 27/1, 2021 at 8:2 Comment(0)
M
0

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>
Megilp answered 17/1, 2021 at 18:59 Comment(0)
P
0

This is my implement with the lack of Action<T...> 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

Perla answered 26/7, 2021 at 4:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.