【问题标题】:List of Strings to hashmap using Streams使用 Streams 到 hashmap 的字符串列表
【发布时间】:2018-02-25 16:47:56
【问题描述】:

我有一个像这样的“,”分隔的字符串数组

a b c d,
f b h j,
l p o i,

我希望将其转换为类似的 Hashmap HashMap<String, List<String>> 使得列表中的第二个元素(由空格分隔成为键,第三个元素成为值) 所以, 这应该变成

b -> c,h
p -> o

我想使用 Streams API,我认为这是要走的路:

List<String> entries = new ArrayList<>();
HashMap<String, List<String>> map = new HashMap<>();

HashMap<String, List<String>> newMap = entries.stream()
    .collect(line -> {
        if (map.contains(line.split(" ")[1])) {
            // Get existing list and add the element
            map.get(line.split(" ")[1].add(line.split(" ")[1]));
        } else {
            // Create a new list and add
            List<String> values = new ArrayList<>();
            values.add(line.split(" ")[1]);
            map.put(line.split(" ")[0], values);
        }
    });

有没有更好的方法?我应该如何从 collect 函数返回 Hashmap?

【问题讨论】:

  • 有没有更好的方法? 鉴于您的代码无法编译,是的,有更好的方法。如果您的问题确实是这样,请尝试至少发布可以按预期编译和工作并且格式正确的代码。
  • 元素是包含在列表还是数组中?
  • 如果你真的想了解,首先从阅读文档中的Collector的原理开始(实际上阅读docs.oracle.com/javase/8/docs/api/java/util/stream/…中的所有内容)。然后阅读 Arrays.stream()、Collectors.groupingBy()、Collectors.mapping() 和 Collectors.toList() 的文档。这些是您需要使用的部分。
  • @Aominè : 元素包含在列表中。
  • @JBNizet:修改了代码。我已阅读,但我不确定如何处理。任何帮助将不胜感激!

标签: java collections hashmap java-stream


【解决方案1】:

您可以使用Collectors.groupingBy 如下所示对输入进行分组(按照内联 cmets):

String[] inputs = {"a b c d,", "f b h j,", "l p o i,"};
Map<String, List<String>> results =  
     Arrays.stream(inputs).map(s -> s.split(" ")).//splt with space
     collect(Collectors.groupingBy(arr -> arr[1], // Make second element as the key
         Collectors.mapping(arr -> arr[2], // Make third element as the value
                            Collectors.toList())));//collect the values to List
 System.out.println(results);

输出:

{p=[o], b=[c, h]}

我建议您阅读 API here 以了解 Collectors.groupingByCollectors.mapping 的工作原理。

【讨论】:

  • 谢谢。一定会的!
【解决方案2】:

您可以使用groupingBy 收集器和Collectors.mapping 作为下游收集器来完成手头的任务。

Map<String, List<String>> collect =
            myList.stream()
                  .map(s -> s.split(" "))
                  .collect(Collectors.groupingBy(a -> a[1],  
                         Collectors.mapping(a -> a[2], Collectors.toList())));

输出:

{p=[o], b=[c, h]}

如果你想保持插入顺序,那么你可以像这样指定LinkedHashMap

Map<String, List<String>> collect =
                myList.stream()
                      .map(s -> s.split(" "))
                      .collect(Collectors.groupingBy(s -> s[1],
                             LinkedHashMap::new,
                              Collectors.mapping(s -> s[2], Collectors.toList())));

输出:

{b=[c, h], p=[o]}

【讨论】:

    【解决方案3】:

    如果你想要 HashMap,而不仅仅是任何 Map

    HashMap<String, List<String>> output =myList.stream().map(s -> s.split(" "))
                .collect(Collectors.groupingBy((s) -> s[1],
                        HashMap::new,
                        Collectors.mapping(
                                (s) -> s[2],
                                Collectors.toList())));
    

    【讨论】:

      猜你喜欢
      • 2018-09-16
      • 2014-04-15
      • 1970-01-01
      • 2018-03-26
      • 2013-01-28
      • 2017-10-01
      • 1970-01-01
      • 2013-01-21
      • 2016-11-09
      相关资源
      最近更新 更多