【问题标题】:Java 8 is not maintaining the order while groupingJava 8 在分组时不保持顺序
【发布时间】:2015-04-30 02:40:09
【问题描述】:

我正在使用 Java 8 按数据分组。但是得到的结果并不是按顺序形成的。

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;
        }

    }

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

【问题讨论】:

    标签: java-8 grouping java-stream collect


    【解决方案1】:

    不维护顺序是存储结果的Map 的属性。如果您需要特定的Map 行为,则需要request a particular Map implementation。例如。 LinkedHashMap 维护插入顺序:

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

    顺便说一句,在创建Stream 之前,没有理由将mapList 的内容复制到一个数组中。您只需拨打mapList.stream() 即可获得合适的Stream

    此外,Collectors.mapping((Map&lt;String, Object&gt; p) -&gt; p, toList()) 已过时。 p-&gt;p 是一个身份映射,所以根本没有理由请求 mapping

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

    但即使是GroupingKey 也已过时。它基本上包装了 List 的值,因此您可以首先使用 List 作为键。 Lists 适当地实现 hashCodeequals(但您不得之后修改这些键 Lists)。

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

    【讨论】:

    • Thanx Holger 你让我的任务变得更简单了。但是我仍然有一个问题,如果我只想在这个 groupedColumns 中应用排序,那么我应该怎么做?
    • 方法toList()未定义,是Collections.toList吗?
    • @geneb。 Collectors.toList()。合并收集器时,您可以使用import static java.util.stream.Collectors.*; 来避免Collectors. 的重复。
    【解决方案2】:

    基于@Holger 的出色回答。我发布此内容是为了帮助那些希望在分组以及更改映射后保持顺序的人。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 2018-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多