Java 8 Collectors.toMap SortedMap

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31004899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:30:55  来源:igfitidea点击:

Java 8 Collectors.toMap SortedMap

javalambdajava-8java-streamcollectors

提问by Robert Bain

I'm using Java 8 lambdas and want to use CollectorstoMapto return a SortedMap. The best I can come up with is to call the following CollectorstoMapmethod with a dummy mergeFunctionand mapSupplierequal to TreeMap::new.

我正在使用 Java 8 lambdas 并想用它CollectorstoMap来返回一个SortedMap. 我能想出的最好的CollectorstoMap方法是用一个 dummymergeFunctionmapSupplier等于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);
}

I don't want to pass in a merge function though, as I just want throwingMerger(), in the same way as the basic toMapimplementation as follows:

我不想传递合并函数,正如我所希望的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);
}

What would be the best practise method of using Collectorsto return a SortedMap?

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

采纳答案by dkatzel

I don't think you can get much better than this:

我认为没有比这更好的了:

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

where the throwlambda is the same as throwingMerger()but I can't directly call that since it's package private (you can of course always make your own static method for that like throwingMerger()is. )

throwlambda与lambda 相同,throwingMerger()但我不能直接调用它,因为它是私有的(当然,您当然可以始终为此创建自己的静态方法throwingMerger()。)

回答by Robert Bain

Based on dkatzel's confirmation that there's not a nice API method, I've opted for maintaining my own custom Collectors class:

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

}

回答by Tagir Valeev

Seems that there's no standard way to do this without defining your own throwingMerger()method or using explicit lambda. In my StreamEx library I defined the toSortedMapmethod which also usesmy own throwingMerger().

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

回答by Daniel

Another way you can do this is to allow Collectors.toMap() to return whatever map it is going to return, and then pass that to a new TreeMap<>().

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

The caveat there is that this only works if your "hashCode()+equals()" and "compareTo" are consistent. If they aren't consistent, then you'll end up with the HashMap removing different set of keys than your TreeMap.

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

回答by uwe

If you use the guava library then you can use:

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

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

The resulting map will be a SortedMapand also immutable.

生成的映射将是一个SortedMap并且也是不可变的。