【问题标题】:Transform List of object to a Map in java在java中将对象列表转换为地图
【发布时间】:2021-12-22 03:00:51
【问题描述】:

我有一个项目列表List<Item> resultBl,如下所示:

id  = 18003  amount = 128 nameType = SUBMITTED
id  = 18189 amount = 95 nameType = SUBMITTED
id  = 18192 amount = 160 nameType = POSITIVE
id  = 18192 amount = 30 nameType = DRAFT
id  = 18192 amount = 873 nameType = SUBMITTED
id  = 18237 amount = 390 nameType = POSITIVE
id  = 18237 amount = 60 nameType = DRAFT
id  = 18237 amount = 2731 nameType = SUBMITTED

我想用这种形式将此列表转换为map,键是id,值是对象的list

Map<Integer,List<ItemDetails>> mapTest= new HashMap<Integer,List<ItemDetails>>();
[18237 , [amount = 390 ,nameType = POSITIVE],[amount = 60 nameType = DRAFT], [amount = 2731 nameType = SUBMITTED]], ...

我尝试了不同的方法,但总是有重复的元素:

List<Integer> ids2 = new ArrayList<Integer>();
List<Integer> ids = new ArrayList<Integer>();

for(Item item: resultBl) {
  ids.add(item.getId());
}

ids2 =ids.stream().distinct().collect(Collectors.toList());
Map<Integer,List<ItemDetails>>  mapTest= new HashMap<Integer,List<ItemDetails>>();
List<ItemDetails> itemDetailsList = new ArrayList<ItemDetails>();
for(Integer s:ids2) {
    for(Item i : resultBl) {
      if(s.equals(i.getId())) {
         ItemDetails it =new ItemDetails();
         it.setAmount(i.getAmount());
         it.setNameType(i.getNameType()) ;
         itemDetailsList .add(it);
      }
    }
    mapTest.put(s, itemDetailsList);
}

【问题讨论】:

    标签: java list hashmap


    【解决方案1】:

    Collectors.groupingByCollectors.mapping 对应 downstream 应该可以工作:

    Map<Integer, List<ItemDetails>> result = resultBl.stream().collect(Collectors.groupingBy(Item::getId, Collectors.mapping(ItemDetails::new, Collectors.toList())));
    

    【讨论】:

    • 我遇到了这个错误:Collectors 类型中的方法 mapping(Function super T,? extends U>, Collector super U,A,R>) 不适用于参数 ( ItemDetails::new, Collector>)
    • ItemDetails 应该有 ItemDetail(Item item) 构造函数。否则你应该实现映射器函数而不是使用ItemDetails::new
    【解决方案2】:

    我会使用流和groupingBy 来做到这一点。

    当您拥有物品清单resultBl 时,您所要做的就是

    Map<Integer, List<Item>> resultMap = resultBl.stream().collect(groupingBy(Item::getId, toList()));
    

    进口:

    import static java.util.stream.Collectors.groupingBy;
    import static java.util.stream.Collectors.toList;
    

    这将按id 参数对您的项目进行分组。

    【讨论】:

    • 很好,但这忽略了地图的值应该是ItemDetails 的列表,而不是Item 的列表。
    【解决方案3】:

    您最好的选择是向ItemDetails 添加一个接受Item 对象的构造函数:

    public class ItemDetails {
    
        // properties, getters and setters
    
        public ItemDetails(Item item) {
            this.amount = item.getAmount();
            this.nameType = item.getNameType();
        }
    
    }
    

    然后使用以下 Java 8 功能:

    Map<Integer, List<ItemDetails>> itemsPerId = 
      itemsList.stream().collect(Collectors.groupingBy(Item::getId, Collectors.mapping(ItemDetails::new, Collectors.toList())));
    

    【讨论】:

      【解决方案4】:
      Map<Integer,List<Item>>  map = resultBL.stream(Collectors.toMap(Item::getId, Function.identity()));
      

      这是拉姆达。 Java 版本 >= 8

      【讨论】:

      • 这看起来不对。 List.stream() 不接受参数。看起来你忘记了collect
      • 另外,地图的值应该是ItemDetails的列表,而不是Item的列表。
      • 感谢您的回答,但它不起作用
      猜你喜欢
      • 2019-03-24
      • 2017-09-02
      • 1970-01-01
      • 2019-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      相关资源
      最近更新 更多