2016-02-06 180 views
0

从地图创建地图的SortedMap的我已经有条目的地图如下使用lambda表达式

[{a.p=aa}, {a.r=aaaa}, {a.q=aaa}, {a.s=aaaaa}, {b.p=bb}, 
{b.r=bbbb}, {c.r=cccc}, {c.q=ccc}, {d.s=ddddd}, {d.p=ddd}] 

我想“的SortedMap”的地图如下使用lambda表达式

[{a=[{a.p=aa}, {a.q=aaa}, {a.r=aaaa}, {a.s=aaaaa}]}, 
{b=[{b.p=bb}, {b.r=bbbb}]}, 
{c=[{c.q=ccc}, {c.r=cccc}]}, 
{d=[{d.p=aaaaa}, {d.s=ddddd}]}] 

回答

0
Supplier<SortedMap<String, String>> supplier = new Supplier<SortedMap<String, String>>() { 

     @Override 
     public SortedMap<String, String> get() { 
      return new TreeMap<String, String>((a, b) -> a.compareTo(b)); 
     } 
    }; 

    // [{a.p=aa}, {a.r=aaaa}, {a.q=aaa}, {a.s=aaaaa}, {b.p=bb}, {b.r=bbbb}, {c.r=cccc}, {c.q=ccc}, {d.s=ddddd}, {d.p=ddd}] 
    Map<String, String> map = new HashMap<String, String>(); 
    map.put("a.p", "aa"); 
    map.put("a.r", "aaaa"); 
    map.put("a.q", "aaa"); 
    map.put("a.s", "aaaaa"); 
    map.put("b.p", "bb"); 
    map.put("b.r", "bbbb"); 
    map.put("c.r", "cccc"); 
    map.put("c.q", "ccc"); 
    map.put("d.s", "ddddd"); 
    map.put("d.p", "aaaa"); 

    Map<String, SortedMap<String, String>> collect = map 
      .entrySet() 
      .stream() 
      .collect(
        Collectors.groupingBy((k -> k.getKey().substring(0, k.getKey().indexOf('.'))), 
          Collectors.toMap(k -> ((Entry<String, String>) k).getKey(), k -> ((Entry<String, String>) k).getValue(), (a, b) -> a, supplier))); 
+0

为什么不使用lambda而不是供应商匿名类?在这里指定比较器有什么意义?为什么不使用'TreeMap :: new'? –

+0

你不需要在这里输入'(Entry )k'。你也可以使用方法引用:'Map.Entry :: getKey' - 'Map.Entry :: getValue'。 – Tunaki

+0

把suppilier这里说,如果我们需要有一个复杂的比较,我们可以使用它,例如如果我们有关键字a.p.1,a.p.4,a.p.2,b.p.2,b.p.20,b.p.1。在这个例子中,如果需要在数字部分完成排序,那么默认比较器不会工作,它需要编写一些逻辑根据键中的numaric值对键进行排序。是的,如果TreeMap的默认构造函数是使用的,你是对的,你可以使用你提到的。谢谢! –