收集 HashMap<String, List<String>> java 8

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24917053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 15:43:26  来源:igfitidea点击:

collecting HashMap<String, List<String>> java 8

javalisthashmapjava-8collectors

提问by user3869813

I want to be able to convert a Listto a HashMapwhere the key is the elementNameand the values is a list of something random (in this case its the Element Name). So in short I want (A->List(A), B->List(B), C-> List(C)). I tried using toMap()and passing it the keyMapperand ValueMapperbut I get a compilation error. I would really appreciate if someone can help me out.

我希望能够将 a 转换List为 a HashMap,其中键是 theelementName并且值是随机列表(在这种情况下是元素名称)。所以简而言之,我想要 ( A->List(A), B->List(B), C-> List(C))。我尝试使用toMap()并传递它keyMapperValueMapper但出现编译错误。如果有人可以帮助我,我将不胜感激。

Thanks!

谢谢!

public static void main(String[] args) {
    // TODO Auto-generated method stub
    List<String> list = Arrays.asList("A","B","C","D");
    Map<String, List<String>> map = list.stream().map((element)->{
        Map<String, List<String>> map = new HashMap<>();
        map.put(element, Arrays.asList(element));
        return map;
    }).collect(??);
}


Function<Map<String, String>, String> key = (map) -> {
    return map.keySet().stream().findFirst().get();
};

Function<Map<String, String>, String> value = (map) -> {
    return map.values().stream().findFirst().get();
};

=== This worked for me

===这对我有用

Thanks for all the help guys! @izstas "they should operate on the elements" helped a lot :). Actually this is what I was looking for to be exact

感谢所有帮助的家伙!@izstas“他们应该对元素进行操作”有很大帮助:)。实际上,这正是我想要的

public static void test2 (){
    Function<Entry<String, List<String>>, String> key = (entry) -> {
        return entry.getKey();
    };
    Function<Entry<String, List<String>>, List<String>> value = (entry) -> {
        return new ArrayList<String>(entry.getValue());
    };
    BinaryOperator<List<String>> merge = (old, latest)->{
        old.addAll(latest);
        return old;
    };

    Map<String, List<String>> map1 = new HashMap<>();
    map1.put("A", Arrays.asList("A1", "A2"));
    map1.put("B", Arrays.asList("B1"));
    map1.put("D", Arrays.asList("D1"));

    Map<String, List<String>> map2 = new HashMap<>();
    map2.put("C", Arrays.asList("C1","C2"));
    map2.put("D", Arrays.asList("D2"));

    Stream<Map<String, List<String>>> stream =Stream.of(map1, map2);
    System.out.println(stream.flatMap((map)->{
        return map.entrySet().stream(); 
    }).collect(Collectors.toMap(key, value, merge)));
}

采纳答案by izstas

Functions keyand valueyou have defined in your code are not correct because they should operate on the elementsof your list, and your elements are not Maps.

函数keyvalue您在代码中定义的不正确,因为它们应该对列表的元素进行操作,而您的元素不是Maps。

The following code works for me:

以下代码对我有用:

List<String> list = Arrays.asList("A", "B", "C", "D");
Map<String, List<String>> map = list.stream()
        .collect(Collectors.toMap(Function.identity(), Arrays::asList));

First argument to Collectors.toMapdefines how to make a key from the list element (leaving it as is), second argument defines how to make a value (making an ArrayListwith a single element).

第一个参数 toCollectors.toMap定义如何从列表元素创建一个键(保持原样),第二个参数定义如何创建一个值(ArrayList用单个元素创建一个)。

回答by user3869813

Thanks for all the help guys! @izstas "they should operate on the elements" helped a lot :). Actually this is what I was looking for to be exact

感谢所有帮助的家伙!@izstas“他们应该对元素进行操作”有很大帮助:)。实际上,这正是我想要的

public static void test2 (){
    Function<Entry<String, List<String>>, String> key = (entry) -> {
        return entry.getKey();
    };
    Function<Entry<String, List<String>>, List<String>> value = (entry) -> {
        return new ArrayList<String>(entry.getValue());
    };
    BinaryOperator<List<String>> merge = (old, latest)->{
        old.addAll(latest);
        return old;
    };

    Map<String, List<String>> map1 = new HashMap<>();
    map1.put("A", Arrays.asList("A1", "A2"));
    map1.put("B", Arrays.asList("B1"));
    map1.put("D", Arrays.asList("D1"));

    Map<String, List<String>> map2 = new HashMap<>();
    map2.put("C", Arrays.asList("C1","C2"));
    map2.put("D", Arrays.asList("D2"));

    Stream<Map<String, List<String>>> stream =Stream.of(map1, map2);
    System.out.println(stream.flatMap((map)->{
        return map.entrySet().stream(); 
    }).collect(Collectors.toMap(key, value, merge)));
}

回答by Phoenix

You can use the groupingBymethod to manage aggregation, for example:

您可以使用该groupingBy方法来管理聚合,例如:

public static void main(String[] args) {
    List<String> list = Arrays.asList("A", "B", "C", "D", "A");
    Map<String, List<String>> map = list.stream().collect(groupingBy(Function.identity()));
}

If you want more flexibility (for example to map the value and return a Set instead of a List) you can always use the groupingBymethod with more parameters as specified in javadoc:

如果您想要更大的灵活性(例如映射值并返回一个 Set 而不是一个列表),您总是可以使用groupingBy具有更多参数的方法,如 javadoc 中指定的:

Map<City, Set<String>> namesByCity = people.stream().collect(groupingBy(Person::getCity, mapping(Person::getLastName, toSet())));