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

I want to be able to convert a List to a HashMap where the key is the elementName and 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 keyMapper and ValueMapper but I get a compilation error. I would really appreciate if someone can help me out.

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

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

Answers


Functions key and value you have defined in your code are not correct because they should operate on the elements of your list, and your elements are not 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.toMap defines how to make a key from the list element (leaving it as is), second argument defines how to make a value (making an ArrayList with a single element).


You can use the groupingBy method to manage aggregation, for example:

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 groupingBy method with more parameters as specified in javadoc:

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

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

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

Need Your Help

How to generate core dumps in Mac OS X?

macos coredump

It seems like I can not generate core dumps in Mac OS X 10.6.8.

How do I find an image contained within an image?

python image-processing opencv

I'm currently building what basically amounts to a cross between a search engine and a gallery for web comics that's focused on citing sources and giving authors credit.