Java相当于Func和Action

rip*_*234 77 java

什么是Java的FuncAction等价物?

我的意思是,而不是自己写这个:

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)

  • 我们真的需要为这个答案投票,因为这个问题是当前“Java 等效操作”的排名第一的搜索结果,现在是 2015 年,所以 Java 8 的东西比 Java 以前的要好得多,并且在这方面几乎模仿了 .net 的东西观点。 (2认同)
  • 除了 `Function&lt;T, R&gt;` 和 `Consumer&lt;T&gt;` 之外,您还可以找到 Java 提供的全套常用功能接口 [此处](https://docs.oracle.com/javase/8/ docs/api/java/util/function/package-summary.html)。 (2认同)

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)

  • Func与Callable的区别在于,存在多达16个参数的泛型重载(Func <TResult>,Func <T,TResult>,Func <T1,T2,TResult>等).OTOH,Callable不接受任何争论.而且,由于泛型中的类型擦除,不可能实现C#的重载. (13认同)

Ale*_*sky 5

重载函数功能的代表(除委托VS匿名类问题)的优雅是,他们从0到16个参数支持(Func<TResult>,Func<T, TResult>,Func<T1, T2, TResult>等)

不幸的是,由于类型擦除,这在Java中是不可能的.只有泛型类型参数才能使类不同.

Java 8现在引入了一个像BiConsumerfor Action<T, T2>和的名称的动物园,因为Java不允许原始类型参数,BiIntConsumer.但是,"动物园"并不是很大,而且我不知道有一个扩展它的图书馆.函数类型文字有一个很好的建议,(int, int) => void但它没有被采纳.

  • 有趣的是,在CLR级别上,只有通用参数数量不同的类别才有不同的名称.``Func`1``等.只是C#将它们映射到同一个名字. (3认同)

use*_*602 5

您可以像这样使用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)


Agi*_*Jon 3

这些确实没有对应的东西。您可以在 Java 中创建匿名内部类,但往往有特定的接口,而不是像 Func 和 Action 这样的通用接口。