Java 8 Collectors.toMap 排序映射
Java 8 Collectors.toMap SortedMap
我正在使用 Java 8 个 lambda,并且想使用 Collectors
toMap
到 return 一个 SortedMap
。我能想到的最好方法是调用以下 Collectors
toMap
方法,其中的虚拟 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
到 return 和 SortedMap
的最佳实践方法是什么?
我认为没有比这更好的了:
.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()
相同,但我不能直接调用它,因为它是包私有的(当然你总是可以为它创建自己的静态方法,比如 throwingMerger()
是。)
基于 dkatzel 确认没有好的 API 方法,我选择维护我自己的自定义收集器 class:
public final class WhosebugExampleCollectors {
private WhosebugExampleCollectors() {
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
method which also uses 我自己的 throwingMerger()
.
另一种方法是允许 Collectors.toMap() 到 return 它要到 return 的任何地图,然后将其传递给新的 TreeMap<>( ).
需要注意的是,这仅在您的 "hashCode()+equals()" 和 "compareTo" 一致时才有效。如果它们不一致,那么最终 HashMap 会删除与 TreeMap 不同的一组键。
如果你使用番石榴库那么你可以使用:
.collect(ImmutableSortedMap.toImmutableSortedMap(comparator, keyMapper, valueMapper));
生成的地图将是 SortedMap
并且也是不可变的。
我正在使用 Java 8 个 lambda,并且想使用 Collectors
toMap
到 return 一个 SortedMap
。我能想到的最好方法是调用以下 Collectors
toMap
方法,其中的虚拟 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
到 return 和 SortedMap
的最佳实践方法是什么?
我认为没有比这更好的了:
.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()
相同,但我不能直接调用它,因为它是包私有的(当然你总是可以为它创建自己的静态方法,比如 throwingMerger()
是。)
基于 dkatzel 确认没有好的 API 方法,我选择维护我自己的自定义收集器 class:
public final class WhosebugExampleCollectors {
private WhosebugExampleCollectors() {
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
method which also uses 我自己的 throwingMerger()
.
另一种方法是允许 Collectors.toMap() 到 return 它要到 return 的任何地图,然后将其传递给新的 TreeMap<>( ).
需要注意的是,这仅在您的 "hashCode()+equals()" 和 "compareTo" 一致时才有效。如果它们不一致,那么最终 HashMap 会删除与 TreeMap 不同的一组键。
如果你使用番石榴库那么你可以使用:
.collect(ImmutableSortedMap.toImmutableSortedMap(comparator, keyMapper, valueMapper));
生成的地图将是 SortedMap
并且也是不可变的。