简体   繁体   English

使用Streams哈希映射的字符串列表

[英]List of Strings to hashmap using Streams

I have a "," separated String array like this 我有一个这样的“,”分隔的字符串数组

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

I would like this to be converted to a Hashmap like HashMap<String, List<String>> such that second element in list (delimited by space becomes key and the 3rd element becomes value) So, This should become 我希望将其转换为类似HashMap<String, List<String>>的Hashmap HashMap<String, List<String>>以便列表中的第二个元素(由空格分隔成为键,第三个元素变为值),所以,这应该成为

b -> c,h
p -> o

I want to use Streams API and I think this is the way to go: 我想使用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);
        }
    });

Is there any better way? 有什么更好的办法吗? How exactly should I return Hashmap from collect function? 我究竟应该如何从collect函数返回Hashmap?

You can use the Collectors.groupingBy as shown below to group the inputs (follow the inline comments): 您可以如下所示使用Collectors.groupingBy对输入进行分组(遵循内联注释):

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);

Output: 输出:

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

I suggest you read the API here to understand how Collectors.groupingBy along with Collectors.mapping works. 建议您在此处阅读API 以了解Collectors.groupingByCollectors.mapping工作方式。

You can achieve the task at hand using a groupingBy collector along with Collectors.mapping as a downstream collector. 您可以使用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())));

output: 输出:

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

if you want to maintain insertion order then you can specify a LinkedHashMap like this: 如果要维持插入顺序,则可以指定一个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())));

output: 输出:

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

If you want HashMap , not just any Map 如果您需要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())));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM