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

时间:2014-07-16 11:08:40

标签: java c# lambda java-8 java-stream

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

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

有没有简单的方法,不需要定义新的功能界面?

4 个答案:

答案 0 :(得分:39)

对于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");

输出是:

1.0;2;s

足以拥有一个参数的函数来表达任意数量的参数的函数: https://en.wikipedia.org/wiki/Currying#Lambda_calculi

答案 1 :(得分:17)

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

答案 2 :(得分:3)

为自己定义功能接口非常容易。在我目前正在进行的项目中,我发现有几次将方法作为参数传递使我能够保持代码的良好和干燥。以下是我定义的一些功能界面:

@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);
}

以下是接受这些参数的方法:

private void loadAnnotations(String annotationType, VoidFunction afterLoadFunction, List<Path> documentPaths) {

这里我用不同的方法将这些方法称为参数:

loadAnnotations(DocumentReader.REDACTION_ANNOTATION_TYPE, this::afterLoadRedactions, documentPaths);
loadAnnotations(DocumentReader.HIGHLIGHT_ANNOTATION_TYPE, this::afterLoadHighlights, documentPaths);

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

答案 3 :(得分:2)

  

有没有简单的方法,不需要定义新的功能界面?

对象可以包含任意数量的其他对象。 Streams API旨在一次只传输一个对象,如果需要更多,您可以将它们包装在一个包含所有对象的对象中。

e.g。

Map<String, Long> map = new HashMap<>();
// each entry has a key and a value as Map.Entry<String, Long>
Map<Long, String> revMap = map.entrySet().stream()
            .collect(groupingBy(Entry::getValue(), HashMap::new, Entry::getKey));