Java 的 Func 和 Action 等价物
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1184418/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java's equivalents of Func and Action
提问by ripper234
回答by AgileJon
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.
对于那些真的没有等价物。您可以在 Java 中创建匿名内部类,但往往有特定的接口,而不是像 Func 和 Action 这样的通用接口。
回答by Andrew Hare
Java doesn't have the concept of delegates. For a workaround approach, please see A Java Programmer Looks at C# Delegates:
Java 没有委托的概念。有关变通方法,请参阅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.
虽然 C# 具有一组类似于 Java 的功能,但它添加了一些新的有趣的功能。委托是将方法视为一流对象的能力。AC# 委托用于 Java 开发人员使用带有单个方法的接口的地方。在本文中,讨论了 C# 中委托的使用,并提供了可以执行类似功能的 Java Delegate 对象的代码。在此处下载源代码。
回答by Gregory Mostizky
Callableinterface is similar to Func.
Callable接口类似于 Func。
Runnableinterface is similar to Action.
Runnable接口类似于 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:
通常,Java 使用匿名内部类来替代 C# 委托。例如,这是添加代码以对 GUI 中的按钮按下做出反应的方式:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
}
});
回答by Aleksandr Dubinsky
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.)
重载函数功能的代表(除委托VS匿名类问题)的优雅是,他们从0到16个参数支持(Func<TResult>
,Func<T, TResult>
,Func<T1, T2, TResult>
等)
Unfortunately, this is impossible in Java because of type erasure. Classes cannot differ by generic type parameters alone.
不幸的是,由于类型擦除,这在 Java 中是不可能的。类不能仅因泛型类型参数而不同。
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.
Java 8 现在引入了像BiConsumer
forAction<T, T2>
和这样的名称动物园,因为 Java 不允许原始类型参数,BiIntConsumer
. 不过,“动物园”并不是很大,而且我不知道有什么图书馆可以扩展它。有一个关于函数类型文字的绝妙提议,例如(int, int) => void
但没有被采纳。
回答by Richard Cook
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.
在 Java 8 中,等价物分别是java.util.function.Function<T, R>
和java.util.function.Consumer<T>
接口。同样,java.util.function.Predicate<T>
等价于System.Predicate<T>
。正如其他地方提到的,这些是接口而不是委托。
Related aside: I'm currently leaning heavily on the following utility class to do LINQ-like extension method stuff:
相关内容:我目前非常依赖以下实用程序类来执行类似 LINQ 的扩展方法:
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
与我在此介绍的类似 LINQ 的方法不同System.Linq.Enumerable.Where<TSource>
,System.Linq.Enumerable.Select<TSource, TResult>
在将结果集合返回给调用者之前,它们并不懒惰并且完全遍历源集合。尽管如此,我发现它们对于纯粹的语法目的很有用,并且在必要时可以变得懒惰。给定的
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);
}
}
回答by Tim Schruben
For Func<T>
use: java.util.function.Supplier
http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html
对于Func<T>
使用:java.util.function.Supplier
http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html
回答by user2739602
You can use java.util.Functionlike this
你可以像这样使用java.util.Function
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
但是,如果您要将它与多个参数一起使用(如 C# Func 所做的那样),那么您必须按如下方式定义 FunctionalInterface 的版本
@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();
回答by Pierre
For older versions than Java 8
对于比 Java 8 更旧的版本
For method callbacks in C# which I used like this:
对于我这样使用的 C# 中的方法回调:
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
我在 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:
Java方法看起来像:
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:
现在在 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();
}