在Stream.map中没有调用put方法

问题描述 投票:0回答:1

我有一个下面的代码,但没有达到预期的效果,所以我需要一点帮助。我有一个 Set<Confirmation> confirmationSet , List<Import> importsList, Map<String, Verification> verificationMap 和a Map<String, String> comprehensiveMap.

我想实现的是

  1. 遍历一组自定义对象 (Set<Confirmation>) confirmationSet 使用流
  2. 在每次迭代中,我都想 getConfirmationId() 从每一个确认对象中提取,该对象是一个 字符串
  3. 基于 确认ID 得到 Verification 对象
  4. 从给定的 核查 物品 List<Import> importsList
  5. 迭代 List<Import> importsList 使用流
  6. 检查给定的import.getName()是否已经包含于 comprehensiveMap
  7. 如果已经存在,则抛出一个Exception。
  8. 如果不存在,则添加这些属性到地图中comprehensiveMap.put(import.getName(), confirmationId))

我试过的

confirmationSet.stream()
                 .map(Confirmation::getConfirmationId)
                 .map(confId-> verificationMap.get(confId))
                 .map(verifObj-> verifObj.getImportList())
                   .stream()
                     .peek(import -> Optional.of(testMap.containsKey(import.getName()))
                         .orElseThrow(() -> new CustomException("Map already contains this key")))
                     .map(import -> comprehensiveMap.put(import.getName(), confirmationId)));

运行这段代码后 comprehensiveMap 是空的... 我到底做错了什么?

我原来的代码是:

confirmationSet.foreach(confirmation -> {

String confirmationId = confirmation.getConfirmationId();
Verification verification = verificationMap.get(confirmationId);
ImportList importList = verification.getImportList;
  importList.foreach(import -> {
    if(!testMap.containsKey(import.getName()){
       comprehensiveMap.put(import.getName(), confirmationId));
    } else {
      throw new CustomException("Map already contains this key")
   }
  }
});

但我想把它做得更漂亮些 谢谢你。

java list dictionary stream nested
1个回答
3
投票

map 不是一个终端操作,它是用来把一个对象变成另一个对象的。如果你想修改你传递的函数之外的东西,你可能不应该使用它。这只是因为Java Maps的设计方式,才会有这个 put 方法返回一个对象,但这并不总是真的。要实际运行你的函数,你需要收集Stream或做一些其他终端操作。

这里有一个终端操作的列表 (资料来源):

  • toArray()
  • 收集()
  • 计数()
  • 减少()
  • forEach()
  • forEachOrdered()
  • 最小值()
  • max()
  • anyMatch()
  • allMatch()
  • noneMatch()
  • findAny()
  • findFirst()

但是,我认为 map 不是你想要的。因为你想通过流并对每个元素执行一个动作,你应该使用 forEach 而不是,这在这里最合适。它将在这里运行你给它的函数。forEach 取一个 Consumer所以你应该给它一个 "不纯洁 "的函数,来修改外面的东西,比如你在你的 map.

我还建议写出前几篇的文章 map 调用为一个,顺便说一下。

EDIT:我想你的代码现在应该是这样的。

confirmationSet.stream()
  .map(Confirmation::getConfirmationId)
  .forEach(confId -> 
    verificationMap
      .get(confId)
      .getImportList()
      .stream()
      .forEach(impt -> {
        if (!comprehensiveMap.containsKey(impt))
          comprehensiveMap.put(impt);
        else throw new CustomException();
      })
  );
© www.soinside.com 2019 - 2024. All rights reserved.