首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将List<P>中的元素分组到Map<K、List<V>>中,同时保持顺序?

如何将List<P>中的元素分组到Map<K、List<V>>中,同时保持顺序?
EN

Stack Overflow用户
提问于 2015-10-15 21:41:35
回答 3查看 7.8K关注 0票数 18

我有一份取自Google Places API的谷歌PlaceSummary对象的列表。我希望根据他们的Google Place ID收集和分组它们,但也要保留元素的顺序。我认为可行的方法是:

代码语言:javascript
运行
复制
Map<String, List<PlaceSummary>> placesGroupedByPlaceId =
            places.stream()
                  .collect(Collectors.groupingBy(
                          PlaceSummary::getPlaceId,
                          LinkedHashMap::new,
                          Collectors.mapping(PlaceSummary::getPlaceId, toList())
                  ));

但它甚至不能编译。根据Java API documentation on Collectors的说法,看起来应该是这样的。

之前我有这样的代码:

代码语言:javascript
运行
复制
    Map<String, List<PlaceSummary>> placesGroupedByPlaceId = places.stream()
            .collect(Collectors.groupingBy(PlaceSummary::getPlaceId));

然而,Streams API上的标准.collect()不会保留后续HashMap中元素的顺序(显然是因为HashMap是无序的)。我希望输出是一个LinkedHashMap,这样就可以按照每个存储桶的插入顺序对映射进行排序。

但是,我建议的解决方案不能编译。首先,它无法识别PlaceSummary::getPlaceId,因为它说它不是一个函数--尽管我知道它是一个函数。其次,它说我不能将LinkedHashMap<Object, Object>转换成M。M应该是一个泛型集合,所以它应该被接受。

如何使用Java Stream API将列表转换为LinkedHashMap?有没有一种简洁的方法呢?如果它太难理解,我可能会求助于老式的前Java 8方法。

我注意到有another Stack Overflow answer on converting List to LinkedHashMap,但它没有我想要的解决方案,因为我需要收集“this”对象,这是我特别迭代过的对象。

EN

回答 3

Stack Overflow用户

发布于 2015-10-15 22:01:33

我想你对最终收集器有点迷惑了。它只表示每个映射值中需要包含的内容。不需要第二个mapping收集器,因为您只需要原始对象的列表。

代码语言:javascript
运行
复制
    Map<String, List<PlaceSummary>> placesGroupedByPlaceId =
          places.stream()
                .collect(Collectors.groupingBy(PlaceSummary::getPlaceId,
                                               LinkedHashMap::new,
                                               Collectors.toList()));
票数 4
EN

Stack Overflow用户

发布于 2018-09-05 15:42:48

代码语言:javascript
运行
复制
/**
 * I have written this code more generic, if you want then you can group based on any * 
 * instance variable , id, name etc via passing method reference.
**/

class Student {
    private int id;
    private String name;
    public Student(int id, String name) {this.id = id;this.name = name;}
    /**
     * @return the id
     */
    public int getId() {return id;}
    /**
     * @param id
     *            the id to set
     */
    public void setId(int id) {this.id = id;}
    /**
     * @return the name
     */
    public String getName() {return name;}
    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {this.name = name;}
}

public class StudentMain {

    public static void main(String[] args) {

        List<Student> list = new ArrayList<>();
        list.add(new Student(1, "Amit"));
        list.add(new Student(2, "Sumit"));
        list.add(new Student(1, "Ram"));
        list.add(new Student(2, "Shyam"));
        list.add(new Student(3, "Amit"));
        list.add(new Student(4, "Pankaj"));

        Map<?, List<Student>> studentById = groupByStudentId(list,
                Student::getId);
        System.out.println(studentById);

       Map<?, List<Student>> studentByName = groupByStudentId(list,
                Student::getName);
        System.out.println(studentByName);

    }

    private static <K, V> Map<?, List<V>> groupByStudentId(List<V> list,
            Function<V, K> keyFunction) {
        return list.stream().collect(
                Collectors.groupingBy(keyFunction, HashMap::new,
                        Collectors.toList()));
    }
}
票数 0
EN

Stack Overflow用户

发布于 2019-02-27 03:44:20

如果您需要在管理订单的同时进行分组,并应用一个函数(Reduction),可能是计数,我会使用类似这样的方法。

代码语言:javascript
运行
复制
final Map<Integer,Long>map=stream.collect(Collectors.groupingBy(function
   ,LinkedHashMap::new
   ,Collectors.collectingAndThen(Collectors.counting(),Function.identity()))
 )
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33150181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档