//真实代码
Map<Integer, String> m = chatTagMapper.selectBatchIds(returnTagIds)
.stream()
.collect(Collectors.toMap(ChatTagEntity::getId, ChatTagEntity::getName));
tagNames.addAll(m.values());
return tagNames;
//问题
本地正常,开发环境,tagNames和查询的顺序不一样。
定位到java 版本不一样,输出不同。
List<User> users = new ArrayList<>();
User user = new User();
user.name = "Luna";
user.id = 36;
users.add(user);
user = new User();
user.name = "Luna2";
user.id = 100;
users.add(user);
user = new User();
user.name = "Luna3";
user.id = 101;
users.add(user);
Map<Integer, String> x = users
.stream()
.collect(Collectors.toMap(User::getId, User::getName));
System.out.println(x);
//java8 执行 和输入熟悉不一样
{100=Luna2, 36=Luna, 101=Luna3}
//java11 执行 和输入顺序一样
{36=Luna, 100=Luna2, 101=Luna3}
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);
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)
底层调用的是HashMap的 merge
方法。merge 方法会计算哈希值,HashMap内部容器初始大小 16。
处理过程:
最终 print 的时候,100在 36 前面。
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return new CollectorImpl<>(HashMap::new,
uniqKeysMapAccumulator(keyMapper, valueMapper),
uniqKeysMapMerger(),
CH_ID);
//底层调用的是putIfAbsent
private static <T, K, V>
BiConsumer<Map<K, V>, T> uniqKeysMapAccumulator(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
return (map, element) -> {
K k = keyMapper.apply(element);
V v = Objects.requireNonNull(valueMapper.apply(element));
V u = map.putIfAbsent(k, v);
if (u != null) throw duplicateKeyException(k, u, v);
};
}
调用的是 putIfAbsent,底层调用的 putVal,是插入到了链表队尾,而不是头部