【问题标题】:Filter values from Java stream on condition that a value is null在值为空的情况下从 Java 流中过滤值
【发布时间】:2019-11-10 18:59:10
【问题描述】:

如果值满足特定条件或某个值为空,我会尝试从流中获取值:

for (ProjectTask task : tasks) {
   TaskEnrollmentUpdateRequest updateTask = updatedPhase.getTasks().stream()
        .filter(t -> task.getId().equals(t.getId()) || t.getId() == null).findFirst().get();
    if (updateTask != null) {
      if (updateTask.getId() != null) {
        mapper.map(updateTask, task);
      } else {
        TaskEnrollmentUpdateRequest ted = updateTask;
      }
    }
...
}

这个想法是,如果updateTask 已经存在于tasks 数组中,我将使用updateTask 中的值更新task,即它的id 值存在于该数组中的一个对象上。如果 id 为空,如果这是一个新任务,那么我想创建一个新任务以添加到 tasks 数组中。问题是我的过滤器函数正在过滤掉所有具有空 Id 的值,因此我永远无法将它们添加到 tasks 数组中。

这是过滤掉我上面描述的值的正确函数吗?:

t -> task.getId().equals(t.getId()) || t.getId() == null

【问题讨论】:

  • 是的。但 updateTask 不可能为 null,因为 Optional.get() 永远不会返回 null。
  • updateTasktask.getId().equals(t.getId()) 不是比t.getId() == null 更好吗? TaskEnrollmentUpdateRequest ted = updateTask; 的目的是什么?该分配没有任何效果。通常,您应该重新考虑逻辑。您不希望循环执行另一个线性搜索,以匹配每个元素的 id……

标签: java java-stream


【解决方案1】:

你可以试试这个:

tasks.stream()
        .flatMap(task -> updatedPhase.getTasks().stream().map(ut -> Map.entry(task, ut)))
        .filter(e -> e.getValue().getId() == null || e.getKey().getId().equals(e.getValue().getId()))
        .findFirst().ifPresent(e -> {
            if (e.getValue().getId() != null) {
                mapper.map(e.getValue(), e.getKey());
            } else {
                TaskEnrollmentUpdateRequest ted = e.getValue();
            }
        });

【讨论】:

    【解决方案2】:

    按照@JBNizet 所说的,我认为你想要这样的东西:

    for (ProjectTask task : tasks) {
        Optional<TaskEnrollmentUpdateRequest> updateTaskOptional = updatedPhase.getTasks().stream()
                .filter(t -> task.getId().equals(t.getId()) || t.getId() == null).findFirst();
        if (updateTaskOptional.isPresent()) {
            TaskEnrollmentUpdateRequest updateTask = updateTaskOptional.get();
            if (updateTask.getId() != null) {
                ...
            } else {
                ...
            }
        }
    }
    

    如果您的过滤器生成一个空列表,那么.findFirst() 将返回一个空的Optional,并且对其调用.get() 将引发异常,因为它没有任何值。因此,您必须通过检查 .findFirst() 返回的 Optional 是否包含值而不是假设它总是包含值来专门检查这种情况。

    【讨论】:

    • 我喜欢使用updateTaskOptional.ifPresent()f,而不是方法名称中的s)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 2021-10-30
    相关资源
    最近更新 更多