Java的Func和Action的等价物
什么是Java的Func和Action的等价物?
我的意思是,而不是写我自己的:
public interface Func<TInput, TResult> { TResult call(TInput target) throws Exception; } public interface Action<T> { void call(T target) throws Exception; }
在Java 8中,等价物分别是java.util.function.Function<T, R>
和java.util.function.Consumer<T>
接口。 类似地, java.util.function.Predicate<T>
等同于System.Predicate<T>
。 如别处所述,这些是接口而不是代表。
相关的一面:我目前主要依靠以下的工具类来做类似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; } }
不像System.Linq.Enumerable.Where<TSource>
和System.Linq.Enumerable.Select<TSource, TResult>
我在这里呈现的类似LINQ的方法不是懒惰的,在将结果集合返回给调用者之前完全遍历源集合。 尽pipe如此,我发现它们对于纯粹的语法目的是有用的,如果需要的话可以做成懒惰的。 特定
class Widget { public String name() { /* ... */ } }
可以做以下事情:
List<Widget> widgets = /* ... */; Iterable<Widget> filteredWidgets = IterableUtil.where(widgets, w -> w.name().startsWith("some-prefix"));
我更喜欢以下内容:
List<Widget> widgets = /* ... */; List<Widget> filteredWidgets = new ArrayList<Widget>(); for (Widget w : widgets) { if (w.name().startsWith("some-prefix")) { filteredWidgets.add(w); } }
Callable接口类似于Func。
Runnable接口类似于Action。
一般来说,Java使用匿名内部类来替代C#委托。 例如,这是你如何添加代码来对GUI中的button做出反应:
button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ...//code that reacts to the action... } });
重载的Func委托(除了委托vs匿名类问题)的优雅之处在于它们支持0到16个参数( Func<TResult>
, Func<T, TResult>
, Func<T1, T2, TResult>
等)
不幸的是,由于types擦除,这在Java中是不可能的。 类只能通过genericstypes参数来区分。
Java 8现在BiConsumer
了一个名为“ BiConsumer
for Action<T, T2>
的动物园,因为Java不允许原始types参数BiIntConsumer
。 然而,“动物园”并不是很大,我不知道有一个扩展它的图书馆。 有一个像(int, int) => void
这样的函数types文字的奇妙build议,但是没有被采用。
那些真的没有等价物。 你可以用Java创build匿名的内部类,但是往往有特定的接口,而不是像Func和Action这样的通用类。
Java没有委托的概念。 有关解决方法,请参阅Java程序员着眼于C#代表 :
虽然C#有一组与Java类似的function,但它增加了一些新的有趣function。 授权是将方法视为第一类对象的能力。 AC#委托用于Java开发人员使用单一方法的接口。 在本文中,将讨论C#中委托的使用,并为可以执行类似function的Java委托对象提供代码。 在这里下载源代码。
对于Func<T>
使用:java.util.function.Supplier http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html