在使用Stream中提供的Collectors.groupingBy做聚合操作的时候,需要按照一定的规则维护顺序。因为这个terminal operations 最后返回的数据结构是一个Map,所以没有办法直接判断他到底是不是一个有序Map,只能戳到源码里看返回。
顺着代码摸索,
public static <T, K> Collector<T, ?, Map<K, List<T>>>
groupingBy(Function<? super T, ? extends K> classifier) {
return groupingBy(classifier, toList());
}
-------------------
public static <T, K, A, D>
Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
Collector<? super T, A, D> downstream) {
return groupingBy(classifier, HashMap::new, downstream);
}
发现最终返回的是一个HashMap数据结构,所以猜测大概率是一个无序Map。
但是实际返回确实按照我所定为key的值,升序返回。这个Stream类中的Collectors.groupingBy纯度也太高了吧。
之后发现实际上还是HashMap中key值选择的问题。HashMap中的Key和对应的的hashCode()方法有关。而我选择作为Key的类型是Integer这个包装类,他的hashCode方法返回就是值本身。
@Override
public int hashCode() {
return Integer.hashCode(value);
}
---------------------
public static int hashCode(int value) {
return value;
}
所以说,算是HashMap在特殊情况下维护的有序。如果需要在通常情况下排序的话,应该是使用一个有序的数据结构,并定义他的排序方法
Collectors.groupingBy(RoleDTO::getItemId,
() -> new TreeMap<>(Comparator.naturalOrder()),
Collectors.toList())