首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >List<Item> to Map<Type、List<Item>>、排序键、排序值和进程

List<Item> to Map<Type、List<Item>>、排序键、排序值和进程
EN

Stack Overflow用户
提问于 2019-12-18 05:26:43
回答 2查看 81关注 0票数 2

我有一个很大的项目列表,我需要将它们转换为相同类型的项目的映射:

代码语言:javascript
复制
List<Item> items = //10^6 items of different types
Map<Type, List<Item>> itemsByType = new ConcurrentHashMap<>();

for (Item item : items) {
    itemsByType.computeIfAbsent(
        item.getType(), 
        i -> new ArrayList<>()
    ).add(item);
}

然后,按照long类型标识符对每种类型进行排序;并且,按照long项目标识符对每个类型项目列表进行排序。最后,处理有序列表。

这很好用,但我想知道是否有更有效的方法来完成所有这些...?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-18 05:28:50

您可以使用java-8 groupingBy

代码语言:javascript
复制
Map<Type, List<Item>> itemsByType = items.stream()
    .sorted(Comparator) //for any sorting you can use sorted with comparator 
    .collect(Collectors.groupingBy(Item::getType));

如果你想要ConcurrentHashMap,你可以使用groupingByConcurrent

代码语言:javascript
复制
ConcurrentMap<Type, List<Item>> itemsByType = items.stream()
    .collect(Collectors.groupingByConcurrent(Item::getType));

您可以将重载的groupingByTreeMap一起使用,这样就可以根据键对地图进行排序

代码语言:javascript
复制
TreeMap<Type, List<Item>> map = list
    .stream()
    .collect(Collectors.groupingBy(
        Item::Type,
        () -> new TreeMap<>(Comparator.comparingLong(Type::getId)), 
        Collectors.toList()));

您还可以在一个链中收集具有排序键和排序值的映射

代码语言:javascript
复制
Map<Type, List<Item>> str = list1.stream()
    .collect(
        Collectors.groupingBy(
            Item::Type, 
            () -> new TreeMap<>(Comparator.comparingLong(Type::getId)),
            Collectors.collectingAndThen(
                Collectors.toList(),
                list -> list.stream()
                    .sorted(Comparator.comparingLong(Item::getId))
                    .collect(Collectors.toList()))));
票数 1
EN

Stack Overflow用户

发布于 2019-12-18 05:34:19

你可以使用MultiMap,例如guava's。下面是他们的代码示例:

代码语言:javascript
复制
   ListMultimap<String, String> multimap = ArrayListMultimap.create();
   for (President pres : US_PRESIDENTS_IN_ORDER) {
     multimap.put(pres.firstName(), pres.lastName());
   }
   for (String firstName : multimap.keySet()) {
     List<String> lastNames = multimap.get(firstName);
     out.println(firstName + ": " + lastNames);
   }

..。生成如下输出:

代码语言:javascript
复制
   Zachary: [Taylor]
   John: [Adams, Adams, Tyler, Kennedy]  // Remember, Quincy!
   George: [Washington, Bush, Bush]
   Grover: [Cleveland, Cleveland]        // Two, non-consecutive terms, rep'ing NJ!
   ...

TreeMultimap具有排序的键和值,如果我正确理解了您的标题,这就是您想要的。

在需要检查某个键是否存在特定值的情况下,Multimap特别有用,因为在不获取该键的集合然后搜索该集合的情况下,可以支持多重映射:

代码语言:javascript
复制
multimap.containsEntry("John", "Adams");
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59382344

复制
相关文章

相似问题

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