2017-09-01 92 views
0

我有一个嵌套的以下类型的地图LinkedHashMap<String, LinkedHashMap<String, ArrayList<Commit>>>。第一张地图的关键字存储了一些用户名,第二张地图的关键字是用户的存储库名称,在ArrayList里面我有一个对象,具有一些属性,如散列,消息,附加等等。按照第一张地图的关键字和第二张地图的关键字按字母顺序排列整个集合,我如何在同一类型的新集合(对象保持不变)中收集(保存)我的嵌套地图?Java 8:如何排序和收集两个内嵌ArrayList的嵌套地图?

我需要使用lambda和Stream API来做到这一点。这是我想做到这一点的方式:

LinkedHashMap<String, LinkedHashMap<String, ArrayList<Commit>>> sorted = gitUsers.entrySet() 
      .stream() 
      .sorted((u1, u2) -> u1.getKey().compareTo(u2.getKey())) 
      .map(u -> u.getValue() 
        .entrySet() 
        .stream() 
        .sorted((r1, r2) -> collator.compare(r1.getKey(), r2.getKey()))) 
      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,(a, b) -> a, LinkedHashMap::new)); 

我肯定做错了什么,因为我不断收到以下信息:“非静态方法不能从静态上下文中引用”,不能收集地图。我想我无法成功组装我的地图,因为.map()函数和我用过的第二个流。

我知道你会建议我使用TreeMap或排序集合,并在我的lambda中使用.foreach()方法立即打印它(我已经这样做了),但我需要像这样完成我已经在上面描述过。

为了我的编程基础课程的目的,这个问题应该以这种方式解决。希望你的帮助!

P.S.我一直在寻找解决方案很长一段时间,并且到处研究包括Stack Overflow论坛,并没有找到任何相应的解决问题的方法。

+0

gitUsers.entrySet()返回什么类型? – Kostiantyn

+0

gitUsers是以下类型的映射:LinkedHashMap >> gitUsers = new LinkedHashMap <>();'正如我在文章开头提到的那样。它是我通过第一个Map的键和第二个嵌套Map的键排序的初始Map,现在我想收集它 - 两个具有ArrayList的地图都收集到相同类型的Map中。 –

+0

请参阅我的回答。我也建议你重命名你的帖子:*如何做嵌套的地图排序*或因为它是更通用的,因为它是更通用 –

回答

3

你的代码没有编译,甚至我删除排序未知collator比较。

有效的代码是:

Map<String, Map<String, List<Commit>>> collect = h.entrySet() 
     .stream() 
     .sorted(Map.Entry.comparingByKey()) 
     .collect(Collectors.toMap(
       Map.Entry::getKey, 
       e -> e.getValue() 
         .entrySet() 
         .stream() 
         .sorted(Map.Entry.comparingByKey()) 
         .collect(
           Collectors.toMap(
             Map.Entry::getKey, 
             Map.Entry::getValue, 
             (a, b) -> a, 
             LinkedHashMap::new 
           ) 
         ), 
       (a, b) -> a, 
       LinkedHashMap::new 
       ) 
     ); 

请注意,您可以与您的比较,而不是Map.Entry.comparingByKey()取代。

+0

我用'Collat​​or collat​​or = Collat​​or.getInstance();'所以java可以比较像c#那样的字符串并打印先写小写字母再写大写字母。我们的开放式裁判系统需要这个测试来解决这个问题,我忘了在我的例子中改变它,对不起。 非常感谢您的回答并更正了代码!我会立即尝试,并会写回你。 –

+0

我犯了一个错误。更正了我的答案。现在它确定 –

+0

“我也建议你将你的帖子重新命名为:如何进行嵌套地图排序或因为它更通用而失去作用”,但我的问题是要正确收集它。我会尝试重新命名我的帖子并更正确地指定问题。 –

0

2美分,我建议你试试EntryStream为地图流操作提供StreamEx。这是我的Fork of StreamEx的解决方案。

StreamEx.of(gitUsers).sortedBy(Entry::getKey) 
     .toMap(Entry::getKey, 
       e -> EntryStream.of(e.getValue()).sortedBy(Entry::getKey).toMap(LinkedHashMap::new), 
       () -> new LinkedHashMap<>()); 

对我而言,代码简单明了,而且更易于理解。顺便说一下,我认为界面始终是首选。对我来说Map<String, Map<String, List<Commit>>>更好。

+0

谢谢你的解决方案!如果我终于成为开发人员,我会牢记它。 :)我需要一个使用普通Java的解决方案,因为我们的Judge System,它只能使用标准库来测试和编译程序。 –