Java 8 Java 8在分组时不维护顺序

Java 8 Java 8在分组时不维护顺序,java-8,grouping,java-stream,collect,Java 8,Grouping,Java Stream,Collect,我使用Java8按数据分组。但得到的结果并不是有序的 Map<GroupingKey, List<Object>> groupedResult = null; if (!CollectionUtils.isEmpty(groupByColumns)) { Map<String, Object> mapArr[] = new LinkedHashMap[mapList.size()]; if

我使用Java8按数据分组。但得到的结果并不是有序的

Map<GroupingKey, List<Object>> groupedResult = null;

        if (!CollectionUtils.isEmpty(groupByColumns)) {

            Map<String, Object> mapArr[] = new LinkedHashMap[mapList.size()];

            if (!CollectionUtils.isEmpty(mapList)) {
                int count = 0;
                for (LinkedHashMap<String, Object> map : mapList) {
                    mapArr[count++] = map;
                }
            }
            Stream<Map<String, Object>> people = Stream.of(mapArr);
            groupedResult = people
                    .collect(Collectors.groupingBy(p -> new GroupingKey(p, groupByColumns), Collectors.mapping((Map<String, Object> p) -> p, toList())));


public static class GroupingKey 

        public GroupingKey(Map<String, Object> map, List<String> cols) {

            keys = new ArrayList<>();

            for (String col : cols) {
                keys.add(map.get(col));
            }
        }

        // Add appropriate isEqual() ... you IDE should generate this
        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final GroupingKey other = (GroupingKey) obj;
            if (!Objects.equals(this.keys, other.keys)) {
                return false;
            }
            return true;
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = 37 * hash + Objects.hashCode(this.keys);
            return hash;
        }

        @Override
        public String toString() {
            return keys + "";
        }

        public ArrayList<Object> getKeys() {
            return keys;
        }

        public void setKeys(ArrayList<Object> keys) {
            this.keys = keys;
        }

    }
Map groupedResult=null;
如果(!CollectionUtils.isEmpty(groupByColumns)){
Map mapArr[]=新LinkedHashMap[mapList.size()];
如果(!CollectionUtils.isEmpty(映射列表)){
整数计数=0;
用于(LinkedHashMap映射:映射列表){
mapArr[count++]=map;
}
}
人流=人流(mapArr);
groupedResult=人
.collect(Collectors.groupingBy(p->newgroupingkey(p,groupByColumns),Collectors.mapping((Map p)->p,toList()));
公共静态类分组密钥
公共分组键(映射、列表列){
keys=newarraylist();
for(字符串列:cols){
key.add(map.get(col));
}
}
//添加适当的isEqual()…IDE应该生成
@凌驾
公共布尔等于(对象obj){
if(obj==null){
返回false;
}
如果(getClass()!=obj.getClass()){
返回false;
}
最终分组键其他=(分组键)对象;
如果(!Objects.equals(this.keys,other.keys)){
返回false;
}
返回true;
}
@凌驾
公共int hashCode(){
int hash=7;
hash=37*hash+Objects.hashCode(this.keys);
返回散列;
}
@凌驾
公共字符串toString(){
返回键+“”;
}
公共ArrayList getKeys(){
返回键;
}
公共无效设置键(ArrayList键){
this.keys=keys;
}
}

在这里,我使用我的类groupingKey,通过它我可以从ux动态传递。如何以排序形式获取此groupByColumns?

不维护顺序是存储结果的
映射的属性。如果需要特定的
映射
行为,则需要。例如,维护插入顺序:

groupedResult = people.collect(Collectors.groupingBy(
    p -> new GroupingKey(p, groupByColumns),
    LinkedHashMap::new,
    Collectors.mapping((Map<String, Object> p) -> p, toList())));

但即使是
GroupingKey
也已过时。它基本上包装了一个值的
列表
,因此您可以首先使用
列表
作为键<代码>列表
s适当地实现
哈希代码
等于
(但之后不得修改这些键
列表
s)

Map groupedResult=
mapList.stream().collect(Collectors.groupingBy(
p->groupByColumns.stream().map(p::get).collect(toList()),
LinkedHashMap::new,toList());

基于@Holger的精彩答案。我发布这篇文章是为了帮助那些希望在分组和更改映射后保持顺序的人

让我们简化一下,假设我们有一个人员列表(int-age、String-name、String-address…等等),我们希望在保持年龄顺序的同时按年龄对姓名进行分组:

final LinkedHashMap<Integer, List<String> map = myList
            .stream()
            .sorted(Comparator.comparing(p -> p.getAge())) //sort list by ages
            .collect(Collectors.groupingBy(p -> p.getAge()),
                    LinkedHashMap::new, //keeps the order
                    Collectors.mapping(p -> p.getName(), //map name
                            Collectors.toList())));
final LinkedHashMap p.getAge())//按年龄对列表排序
.collect(收集器.groupingBy(p->p.getAge()),
LinkedHashMap::new,//保持顺序
Collectors.mapping(p->p.getName(),//映射名
收藏家;

Thanx Holger u使我的任务更加简单。但我仍然有一个问题,如果我只想在这个wid this groupedColumns中应用排序,那么我应该怎么做?方法
toList()
未定义,是不是Collections.toList?@geneb
Collectors.toList()
。您可以使用
导入静态java.util.stream.Collectors.*
以避免在组合收集器时重复使用
收集器。
Map<List<Object>, List<Object>> groupedResult=
  mapList.stream().collect(Collectors.groupingBy(
    p -> groupByColumns.stream().map(p::get).collect(toList()),
    LinkedHashMap::new, toList()));
final LinkedHashMap<Integer, List<String> map = myList
            .stream()
            .sorted(Comparator.comparing(p -> p.getAge())) //sort list by ages
            .collect(Collectors.groupingBy(p -> p.getAge()),
                    LinkedHashMap::new, //keeps the order
                    Collectors.mapping(p -> p.getName(), //map name
                            Collectors.toList())));