我的意思是,与其说是自己写,不如说是:
public interface Func<TInput, TResult>
{
TResult call(TInput target) throws Exception;
}
public interface Action<T>
{
void call(T target) throws Exception;
}
Answers:
在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类似的方法不同,在将结果集合返回给调用者之前,它们并不懒惰并且完全遍历源集合。不过,我发现它们仅用于语法目的,在必要时可以变得懒惰。给定
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);
}
}
重载函数功能的代表(除委托VS匿名类问题)的优雅是,他们从0到16个参数支持(Func<TResult>,Func<T, TResult>,Func<T1, T2, TResult>等)
不幸的是,由于类型擦除,这在Java中是不可能的。类不能仅因泛型类型参数而有所不同。
Java 8现在引入了诸如BiConsumerforAction<T, T2>和as之类的名称,因为Java不允许使用基本类型参数BiIntConsumer。但是,“ zoo”不是很大,而且我还不知道可以对其进行扩展的库。对于像这样的函数类型文字有一个很棒的建议,(int, int) => void但是没有被采纳。
Func`1等等。只是C#将它们映射到相同的名称。
BiConsumerforAction<T, T2>和as之类的名称BiIntConsumer。对于像这样的函数类型文字提出了一个建议,(int, int) => void但没有被采纳。
对于Func<T>使用:java.util.function.Supplier
http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html
Supplier等同于Func<T>(相对于Func<T1, T2>)not Action。an不Action接受任何参数,也不返回结果。(其他版本的Actionaccept接受各种数量的参数,并且不返回结果。)
Func<T>Java的,但错误地将其记为Action<T>。糟糕
Action<>:0输入,0输出。.andThen(...)功能充其量。
Action<>0输入和0输出。但是请记住,在Java中,这些只是接口。因此,您可以创建自己的使用。
Runnablefor Action<>,尽管它不如新的Java 8功能性东西漂亮。
Java没有委托的概念。有关解决方法,请参见Java程序员看C#委托:
尽管C#具有类似于Java的一组功能,但它增加了一些有趣的新功能。委派是将方法视为一流对象的能力。AC#委托用于Java开发人员将通过单一方法使用接口的情况。在本文中,将讨论C#中委托的使用,并为可执行类似功能的Java委托对象提供代码。在此处下载源代码。
您可以像这样使用java.util.Function
Function<Employee, String> f0 = (e) -> e.toString();
但是,如果您要使用一个以上的参数(就像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);
}
然后,您可以使用不带参数的变量
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();
对于Java 8之前的版本
对于我在C#中使用的方法回调,如下所示:
public void MyMethod(string par1, string par2, Action<int> callback, Action<int, string> callback2)
{
//Async Code
callback.invoke(1);
callback2.invoke(4, "str");
}
并调用它:
utils.MyMethod("par1", "par2", (i) =>
{
//cb result
}, (i, str) =>
{
//cb2 result
});
我已经用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方法如下所示:
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");
}
现在,当用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
}
});
通过将回调传递/设置为您要在其中调用它们的类,这也可以起作用,同样的方法也可以用于创建接口:
package com.example.app.interfaces;
public interface MyInterface<T> {
void makeDo(T obj);
void makeAnotherDo();
}