Kousha
Kousha

Reputation: 36189

Java 8 List<K> into Map<K, List<String>>

I have a list

List<MyObject> list;

And I want to convert this to a map of Map<MyObject, List<String>>

I tried

Map<MyObject, List<String>> map = list
    .stream()
    .collect(Collectors.toMap(item -> item, Collections.emptyList()));

But Java is not happy with the item->item:

no instance(s) of type variable(s) T exists so that List<T> conforms to Function<? super T, ? extends U>

Help is appreciated

Upvotes: 1

Views: 1037

Answers (2)

fps
fps

Reputation: 34450

You haven't specified where the String elements of each List<String> come from.

If they come from each MyObject instance, you could try using Collectors.groupingBy along with Collectors.mapping instead of Collectors.toMap:

Map<MyObject, List<String>> map = list.stream()
    .collect(Collectors.groupingBy(
            item -> item, 
            Collectors.mapping(item -> item.getSomeStringAttribute(),
                    Collectors.toList())));

If, instead of an attribute of MyObject, the elements of each list come from somewhere else, you can encapsulate the acquisition of each String element in a method:

Map<MyObject, List<String>> map = list.stream()
    .collect(Collectors.groupingBy(
            item -> item, 
            Collectors.mapping(item -> someMethod(item),
                    Collectors.toList())));

Where someMethod would be as follows:

String someMethod(MyObject item) {
    // TODO get/calculate the String from the item
}

If, on the other side, you only want to initialize a map with empty lists as values for each MyObject instance, you don't need streams for that:

Map<MyObject, List<String>> map = new HashMap<>();
list.forEach(item -> map.put(item, new ArrayList<>()));

Upvotes: 1

rgettman
rgettman

Reputation: 178243

The second argument to Collectors.toMap expects a Function to convert the item to a value that will be placed in the map. However, you have supplied Collections.emptyList(), which is not a Function.

It looks like you want an empty list for every item, so change

Collections.emptyList()

to

item -> Collections.emptyList()

However, Collections.emptyList() returns an immutable empty list, which is probably not what you want here.

Returns an empty list (immutable). This list is serializable.

You may want

item -> new ArrayList<>()

Upvotes: 3

Related Questions