Java 8 Collectors.toMap SortedMap

后端 未结 5 649
隐瞒了意图╮
隐瞒了意图╮ 2020-12-01 02:28

I\'m using Java 8 lambdas and want to use Collectors toMap to return a SortedMap. The best I can come up with is to call the following

相关标签:
5条回答
  • 2020-12-01 02:59

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

    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);
        }
    
    }
    
    0 讨论(0)
  • 2020-12-01 03:00

    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 throw lambda 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. )

    0 讨论(0)
  • 2020-12-01 03:03

    If you use the guava library then you can use:

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

    The resulting map will be a SortedMap and also immutable.

    0 讨论(0)
  • 2020-12-01 03:14

    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<>().

    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.

    0 讨论(0)
  • 2020-12-01 03:19

    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 toSortedMap method which also uses my own throwingMerger().

    0 讨论(0)
提交回复
热议问题