我有一个流收集器的合并功能,并试图使其通用。由于 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;
};
这已经非常通用了,但我想去掉泛型参数中的显式类型。
答案 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() ) );