泛型参数类型的 Java var 类型推断

时间:2021-03-12 08:34:35

标签: java generics lambda type-inference

我有一个流收集器的合并功能,并试图使其通用。由于 lambda 接受 var 作为参数类型并且结果类型是 BinaryOperator,我试图获得类似 BinaryOperator 或类似的东西。

BinaryOperator<InsertYourFavouriteType> rejectNewValueAndWarn = (oldValue, newValue ) -> {
            LOGGER.warn( "Old value already present in map, rejecting to collect new value" );
            LOGGER.warn( "Old value:" + oldValue );
            LOGGER.warn( "New value:" + newValue );
            return oldValue;
        };

这已经非常通用了,但我想去掉泛型参数中的显式类型。

2 个答案:

答案 0 :(得分:4)

你不能用变量直接1做到这一点,但使用方法完全有可能:

public final class Rejecter {
    public static <T> T rejectNewValueAndWarn(T oldValue, T newValue) {
        LOGGER.warn("Old value already present in map, rejecting to collect new value");
        LOGGER.warn("Old value:" + oldValue);
        LOGGER.warn("New value:" + newValue);
        return oldValue;
    }
}

然后就可以使用方法引用直接引用方法了:

Map<A, B> map = whatever.stream()
    .collect(Collectors.toMap(
        ..., // your key mapper
        ..., // your value mapper
        Rejecter::rejectNewValueAndWarn // the merge function
    ));

1 您可以将泛型参数定义为 ?Object,但随后您需要对每次使用进行强制转换,例如 (BinaryOperator<SomeType>) rejectNewValueAndWarn,有效地消除了将此逻辑提取到公共位置的整个目的。

答案 1 :(得分:2)

好的,在使用泛型类型作为类型参数的提示之后,我想出了一个定义如下的合并函数:

static < K > BinaryOperator< K > mergeFunction()
    {
        BinaryOperator< K > rejectNewValueAndWarn = ( oldValue, newValue ) -> {
            LOGGER.warn( "Old value already present in map, rejecting to collect new value" );
            LOGGER.warn( "Old value:" + oldValue );
            LOGGER.warn( "New value:" + newValue );
            return oldValue;
        };
        return rejectNewValueAndWarn;
    }

blablaList.
            .stream()
            .collect( Collectors.toMap( AbstractDto::getName, Function.identity(), mergeFunction() ) );