Java8 Collectors.toMap SortedMap

我正在使用 Java8 lambdas 并希望使用 Collectors toMap返回一个 SortedMap。我能想到的最好方法是使用等于 TreeMap::new的虚拟 mergeFunctionmapSupplier调用以下 Collectors toMap方法。

public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator = (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}

但是我不想传入一个 merge 函数,因为我只想要 throwingMerger(),与基本的 toMap实现方式相同,如下所示:

public static <T, K, U>
Collector<T, ?, Map<K, U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}

使用 Collectors返回 SortedMap的最佳实践方法是什么?

48358 次浏览

我觉得没有比这更好的了:

.collect(Collectors.toMap(keyMapper, valueMapper,
(v1,v2) ->{ throw new RuntimeException(String.format("Duplicate key for values %s and %s", v1, v2));},
TreeMap::new));

其中 throw lambda 与 throwingMerger()相同,但我不能直接调用它,因为它是包 private (当然,您可以像 throwingMerger()一样为它创建自己的静态方法)

基于 dkatzel 的确认,没有一个很好的 API 方法,我选择维护我自己的自定义 Collector 类:

public final class StackOverflowExampleCollectors {


private StackOverflowExampleCollectors() {
throw new UnsupportedOperationException();
}


private static <T> BinaryOperator<T> throwingMerger() {
return (u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
};
}


public static <T, K, U, M extends Map<K, U>> Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper, Supplier<M> mapSupplier) {
return Collectors.toMap(keyMapper, valueMapper, throwingMerger(), mapSupplier);
}


}

如果不定义自己的 throwingMerger()方法或者使用显式的 lambda,似乎就没有标准的方法可以做到这一点。在我的 StreamEx 库中,我定义了 toSortedMap方法,这也是我自己的 throwingMerger()方法。

另一种方法是允许 Collectors.toMap ()返回它将返回的映射,然后将其传递给一个新的 TreeMap < > ()。

需要注意的是,这只有在“ hashCode () + equals ()”和“ compareTo”是一致的情况下才有效。如果它们不一致,那么最终 HashMap 将删除与 TreeMap 不同的键集。

如果您使用番石榴库,那么您可以使用:

.collect(ImmutableSortedMap.toImmutableSortedMap(comparator, keyMapper, valueMapper));

得到的映射将是 SortedMap并且也是不可变的。