代码之家  ›  专栏  ›  技术社区  ›  Nilotpal

在Java8中,当在流中复制键时,如何收集到一个映射中形成一个值列表

  •  6
  • Nilotpal  · 技术社区  · 7 年前

    我有一个二维数组或二维数组形式的元素流 EntrySet . 我需要把这些收集起来 Map . 现在的问题是元素流可以有重复的元素。假设我希望值是一个列表:

    Map<String,List<String>>
    

    例子:

    class MapUtils
    {
    // Function to get Stream of String[]
    private static Stream<String[]> getMapStream()
    {
        return Stream.of(new String[][] {
                {"CAR", "Audi"},
                {"BIKE", "Harley Davidson"},
                {"BIKE", "Pulsar"}
        });
    }
    
    // Program to convert Stream to Map in Java 8
    public static void main(String args[])
    {
        // get stream of String[]
        Stream<String[]> stream = getMapStream();
    
        // construct a new map from the stream
        Map<String, String> vehicle =
                stream.collect(Collectors.toMap(e -> e[0], e -> e[1]));
    
        System.out.println(vehicle);
    }
    }
    

    java.lang.IllegalStateException: Duplicate key Harley Davidson
    

    我想有个办法

    1. 我可以做手术 e->e[0] e->e[1] 解决问题。有可能吗?为此,我需要一个当前的地图对象正在收集访问。我不确定这是否合理。
    2. 使用Java8流可以实现这一点的方法。

    预期产量:

    {CAR=[Audi], BIKE=[Harley Davidson, Pulsar]}
    
    2 回复  |  直到 7 年前
        1
  •  13
  •   Eran    7 年前

    那是什么 groupingBy 用于:

    Map<String,List<String>> vehicle = 
        stream.collect(Collectors.groupingBy(e -> e[0], 
                       Collectors.mapping(e -> e[1],
                                          Collectors.toList())));
    

    输出映射:

    {CAR=[Audi], BIKE=[Harley Davidson, Pulsar]}
    
        2
  •  3
  •   Hadi Jeddizahed    7 年前

    你可以用 groupingBy

    getMapStream()
          .map(item -> Arrays.asList(item))
          .collect(Collectors.groupingBy(l->l.get(0),
               Collectors.mapping(l1->l1.get(1),Collectors.toList())));
    

    toMap() 具有合并功能。

         Map<String,List<String>> vehicle = getMapStream()
                .collect(Collectors.toMap(item->item[0],
           item->new ArrayList<>(Arrays.asList(item[1])),
                                (l1,l2)->{l1.addAll(l2);return l1;}));