Java 8 Collectors.toMap SortedMap

时间:2015-06-23 14:00:22

标签: java lambda java-8 java-stream collectors

我正在使用Java 8 lambdas并希望使用Collectors toMap来返回SortedMap。我能想到的最好的方法是使用虚拟CollectorstoMap等于mergeFunction来调用以下mapSupplier TreeMap::new方法。

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

我不想传递合并函数,因为我只想要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的最佳做法是什么?

5 个答案:

答案 0 :(得分:59)

我认为你不能比这更好:

.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()相同但我不能直接调用它,因为它是私有的包(当然你总是可以为{{1}创建自己的静态方法是。)

答案 1 :(得分:8)

根据dkatzel的确认,这不是一个不错的API方法,我选择维护自己的自定义收藏家类:

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

}

答案 2 :(得分:7)

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

答案 3 :(得分:4)

另一种方法是允许Collectors.toMap()返回它要返回的任何地图,然后将其传递给新的TreeMap&lt;&gt;()。

需要注意的是,只有当你的&#34; hashCode()+等于()&#34;和&#34; compareTo&#34;是一致的。如果它们不一致,那么您最终将使用HashMap删除不同于TreeMap的键集。

答案 4 :(得分:1)

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

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

生成的地图将是SortedMap并且也是不可变的。