【问题标题】:put method not called in Stream.map在 Stream.map 中未调用 put 方法
【发布时间】:2020-10-02 14:58:33
【问题描述】:

我下面的代码没有按预期工作,所以我需要一点帮助。我有一个Set<Confirmation> confirmationSetList<Import> importsListMap<String, Verification> verificationMap 和一个Map<String, String> comprehensiveMap

我想要实现的是:

  1. 使用流迭代自定义对象集(Set<Confirmation>) confirmationSet
  2. 在每次迭代中,我都想从每个 Confirmation 对象中 getConfirmationId(),它是一个 String
  3. 根据confirmationId获取Verification对象
  4. 从给定的 Verification 对象获取List<Import> importsList
  5. 使用流迭代List<Import> importsList
  6. 检查给定的 import.getName() 是否已经包含在 comprehensiveMap
  7. 如果已经存在,则抛出异常。
  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")
   }
  }
});

但我想让它更漂亮.. 谢谢

【问题讨论】:

  • 您的问题中的testMap 是什么? import 是关键字,不能用作变量。还有ImportList 的课程吗?不分享真正的问题,就很难找到真正的解决方案。

标签: java java-stream mapping


【解决方案1】:

map 不是终端操作,它是用于将一个对象转换为另一个对象。如果你想修改你传递的函数之外的东西,你可能不应该使用它。只是因为 Java Maps 的设计方式,put 方法返回一个对象,但这并不总是正确的。要实际运行您的函数,您需要收集 Stream 或执行其他一些终端操作。

这里是终端操作列表(Source):

  • toArray()
  • 收集()
  • count()
  • 减少()
  • forEach()
  • forEachOrdered()
  • 分钟()
  • 最大()
  • anyMatch()
  • allMatch()
  • noneMatch()
  • findAny()
  • findFirst()

但是,我认为map 不是您想要的。由于您想通过流并对每个元素执行操作,因此您应该使用 forEach 代替,这最适合这里。它将运行您在此处提供的功能。 forEach 接受 Consumer,所以你应该给它“不纯”的函数来修改外部的东西,比如你在 map 中放入的 lambda。

顺便说一下,我还建议将前几个 map 调用合并为一个。

编辑:我认为您的代码现在应该是这样的:

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();
      })
  );

【讨论】:

  • @MarkyMark 您仍然可以保持花哨,只需将最后一个 map 替换为 forEach,其余代码可以保持不变
  • 你能指导我怎么做吗?我有点困惑
  • 我已经删除了评论,因为代码不属于这里并编辑了问题
  • @user 使用 peek 不是一个好主意,它通常用于调试目的
  • @Eklavya 是的,我现在已经对 OP 的代码进行了相当大的更改,尽管我不确定我是否正确解释了它
猜你喜欢
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-29
  • 1970-01-01
  • 2015-08-18
  • 2018-10-14
  • 2018-01-26
相关资源
最近更新 更多