如何使用Java流将LIst <Object>转换为Map <K,V>

问题描述

我想将List<ObjectInList>转换为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
}

新的地图格式如下

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

List<Object>中的每个对象可以具有重复的类型

例如

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

解决方法

您可以使用groupingBy来对type进行分组,并使用flatMapping来平整Long数据列表并作为单个列表进行收集。

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

我不确定为什么Map<String,Object> dataMap;应该只具有一个值时为什么需要它。为简单起见,我将您的ObjectInList类修改为

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

要获取分组列表,我们可以-

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

说明:

toMap方法-

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)

toMapkeyMapperObjectInList::getType(根据类型分组),valueMaper为ObjectInList::getListWithLong,由于我们有重复的密钥,我们需要提供一个{{1 }}为mergeFunction

摘自文档-

合并功能,用于解决关联值之间的冲突 使用与提供给{@link Map#merge(Object,Object, BiFunction)