具有多个参数的Java 8 Consumer在哪里?

Mig*_*boa 36 c# java lambda java-8 java-stream

例如在.Net中,它提供了具有不同数量和类型的参数的Action委托的几个实现(相当于Java Consumer功能接口),我期望Java 8提供了一些方法来指定Consumer不同类型的多个参数.

我知道在Java中我们不能定义具有相同名称的不同类型,这些类型在泛型类型参数中有所不同,但是提供多参数会有很好的流畅替代方案Consumer.

有没有简单的方法可以做到这一点,这不需要定义新的功能界面?

Lev*_*Lev 40

对于3个或更多参数,您可以使用curried(http://en.wikipedia.org/wiki/Currying)函数与最后一个使用者:

Function<Double, Function<Integer, Consumer<String>>> f = d -> i -> s -> {
            System.out.println("" + d+ ";" + i+ ";" + s); 
        };
f.apply(1.0).apply(2).accept("s");
Run Code Online (Sandbox Code Playgroud)

输出是:

1.0;2;s
Run Code Online (Sandbox Code Playgroud)

只需一个参数的函数来表达任意数量的参数的函数就足够了:https: //en.wikipedia.org/wiki/Currying#Lambda_calculi

  • 聪明,但我**敦促**任何人考虑这个只是创建一个新的功能界面. (15认同)
  • 可以在`java.util.stream.Stream.forEach(Consumer <?super T> action)`中使用它吗? (2认同)

Sim*_*mY4 19

默认情况下,您仅限于java.util.function.Consumerjava.util.function.BiConsumer.它们足以用于当前的Java流API.但是,您可以创建自己的功能接口,以接收任意数量的参数,并在您自己的自定义API中使用它.


小智 5

为自己定义功能接口非常容易。在我目前正在从事的项目中,我发现有几次通过将方法作为参数传递使我能够保持代码的美观和DRY。这是我定义的一些功能接口:

@FunctionalInterface
public interface CheckedVoidFunction {
    void apply() throws Exception;
}

@FunctionalInterface
public interface VoidFunction {
    void apply();
}

@FunctionalInterface
public interface SetCategoryMethod {
    void accept(ObservableList<IRegionWithText> list, Document document, String pattern);
}
Run Code Online (Sandbox Code Playgroud)

这是一种接受此类参数的方法:

private void loadAnnotations(String annotationType, VoidFunction afterLoadFunction, List<Path> documentPaths) {
Run Code Online (Sandbox Code Playgroud)

在这里,我用不同的方法作为参数来调用这些方法:

loadAnnotations(DocumentReader.REDACTION_ANNOTATION_TYPE, this::afterLoadRedactions, documentPaths);
loadAnnotations(DocumentReader.HIGHLIGHT_ANNOTATION_TYPE, this::afterLoadHighlights, documentPaths);
Run Code Online (Sandbox Code Playgroud)

也许有更好的方法可以做到这一点,但我想我会分享对我有用的东西。

  • 记录在案:`VoidFunction` -&gt; 内置`Runnable`。 (2认同)