我的意思是,而不是自己写这个:
public interface Func<TInput, TResult>
{
TResult call(TInput target) throws Exception;
}
public interface Action<T>
{
void call(T target) throws Exception;
}
Run Code Online (Sandbox Code Playgroud)
Ric*_*ook 86
在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;
}
}
Run Code Online (Sandbox Code Playgroud)
与此类似的LINQ类方法不同System.Linq.Enumerable.Where<TSource>
,System.Linq.Enumerable.Select<TSource, TResult>
在将结果集合返回给调用者之前,它并不是懒惰的并且完全遍历源集合.尽管如此,我发现它们仅仅用于纯粹的语法目的,并且如果必要可能会变得懒惰.特定
class Widget {
public String name() { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)
人们可以做到以下几点:
List<Widget> widgets = /* ... */;
Iterable<Widget> filteredWidgets = IterableUtil.where(widgets, w -> w.name().startsWith("some-prefix"));
Run Code Online (Sandbox Code Playgroud)
我更喜欢以下内容:
List<Widget> widgets = /* ... */;
List<Widget> filteredWidgets = new ArrayList<Widget>();
for (Widget w : widgets) {
if (w.name().startsWith("some-prefix")) {
filteredWidgets.add(w);
}
}
Run Code Online (Sandbox Code Playgroud)
Gre*_*zky 34
可调用接口类似于Func.
Runnable接口类似于Action.
通常,Java使用匿名内部类作为C#委托的替代.例如,这是您添加代码以响应GUI中的按钮按下的方式:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
}
});
Run Code Online (Sandbox Code Playgroud)
重载函数功能的代表(除委托VS匿名类问题)的优雅是,他们从0到16个参数支持(Func<TResult>
,Func<T, TResult>
,Func<T1, T2, TResult>
等)
不幸的是,由于类型擦除,这在Java中是不可能的.只有泛型类型参数才能使类不同.
Java 8现在引入了一个像BiConsumer
for Action<T, T2>
和的名称的动物园,因为Java不允许原始类型参数,BiIntConsumer
.但是,"动物园"并不是很大,而且我不知道有一个扩展它的图书馆.函数类型文字有一个很好的建议,(int, int) => void
但它没有被采纳.
对于Func<T>
使用:java.util.function.Supplier
http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html
您可以像这样使用java.util.Function
Function<Employee, String> f0 = (e) -> e.toString();
Run Code Online (Sandbox Code Playgroud)
但是,如果您要将它与多个参数一起使用(如 C# Func 所做的那样),那么您必须按如下方式定义您的 FunctionInterface 版本
@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);
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用变量 no of argument
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();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
38490 次 |
最近记录: |