buk
buk

Reputation: 59

How to convert LIst<Object> to Map<K, V> with using java stream

I want to convert List<ObjectInList> to Map<K, V>

class ObjectInList {
    List<Long> listWithLong;
    Map<String, Object> dataMap; // there is 'id' key, and i want to use this id as key in map to be converted
}

The new map format is like below

String type; // this type is value of dataMap.
List<Long> contents

each Object in List<Object> can have duplicated type

for example

///////// before converted ////////////
[
 {
    list: [1,2,3],
    dataMap: {
      type: "a",
    }
 },
 {
    list: [4,5,6],
    dataMap: {
      type: "b",
    }
 },
 {
    list: [7,8],
    dataMap: {
      type: "a",
    }
 },
]
///////////// after converted //////////
{
  "a": [1,2,3,7,8],
  "b": [4,5,6]
}

Upvotes: 0

Views: 133

Answers (2)

Pankaj
Pankaj

Reputation: 2678

I'm not sure why do you need Map<String, Object> dataMap; when it was supposed to have only one value. For simplicity, I have modified your ObjectInList class as

class ObjectInList {
  List<Long> listWithLong;
  String type; 
}

To get grouped list we can do -

Map<String, List<Long>> grouped =
    objectInLists.stream()
        .collect(
            Collectors.toMap(
                ObjectInList::getType,
                ObjectInList::getListWithLong,
                (oldList, newList) -> {
                  oldList.addAll(newList);
                  return oldList;
                }));

Explanation:

toMap method -

public static <T, K, U>
    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                    Function<? super T, ? extends U> valueMapper,
                                    BinaryOperator<U> mergeFunction)

toMap takes keyMapper which is ObjectInList::getType (to group based on type) and valueMaper is ObjectInList::getListWithLongand as we have duplicate key we need to provide a mergeFunction as (oldList, newList) -> {oldList.addAll(newList);return oldList;}

From documentation -

a merge function, used to resolve collisions between values associated with the same key, as supplied to {@link Map#merge(Object, Object, BiFunction)

Upvotes: 0

Eklavya
Eklavya

Reputation: 18410

You can use groupingBy to group by type and flatMapping to flatten list of Long data and collect as single list.

Map<String, List<Long>> res = 
   objectInList
    .stream()
    .collect(Collectors.groupingBy(
                       e -> e.getDataMap().get("type"),
                       Collectors.flatMapping(
                                  e -> e.getListWithLong().stream(),
                                  Collectors.toList())
     ));

Upvotes: 1

Related Questions