Thomas Verhoeven
Thomas Verhoeven

Reputation: 286

Map<String, List<String, Object>> add new list entry when key exists

Let's say I got Map<ID, Object> when looping over the entries via .entrySet().stream()

I want to map it to Map<String, List<Map<String, Object>>

When using toMap() I change the ID of my initial map to a String (with a database call), but different ID's can return the same string so there can be duplicates. Is it possible if my key already exists in the toMap of my new map that I'm collecting, that my ObjectOne is added in a new list entry of my new map in the format of Map<String, List<Map<String, Object>> .

I tried stuff with Collectors.groupingBy() and Collectors.mapping() but not getting it to work, curious if there is a way to do this

What I got now is the following solution, but I would like to collect it to map without having to define it first:

  Map<String, List<Map<String, Object>>> giantMap = new HashMap<>();
   
  initalMap.forEach((id, object) -> {
      Code code = repository.getCodeById(id);
      giantMap.computeIfAbsent(code, ignore -> new ArrayList<>())
                        .add(object);
   });

Upvotes: 1

Views: 1398

Answers (1)

Nowhere Man
Nowhere Man

Reputation: 19565

So, let's assume there is a map of some ids to objects of type ObjectOne: Map<ID, ObjectOne>.

The key IDs are converted to some Code type by a database call, and the ObjectOne values of the first map are just collected into another map using Collectors.groupingBy and Collectors.mapping as intended initially:

Map<ID, ObjectOne> initialMap = ...;

Map<Code, List<ObjectOne>> mapByCode = initialMap
        .entrySet()
        .stream() // Stream<Map.Entry<ID, ObjectOne>>
        .collect(Collectors.groupingBy(
            e -> repository.getCodeById(e.getKey()),
            Collectors.mapping(Map.Entry::getValue, Collectors.toList())
        ));

Also, a keySet of the initial map may be iterated upon:

// or using keySet()
Map<Code, List<ObjectOne>> mapByCode2 = initialMap
        .keySet()
        .stream() // Stream<ID>
        .collect(Collectors.groupingBy(
            repository::getCodeById,
            Collectors.mapping(initialMap::get, Collectors.toList())
        ));

Upvotes: 3

Related Questions