Java8同时过滤和更改属性

dma*_*hop 2 java lambda java-8 java-stream

通读这篇文章,我可以像这样过滤集合:

Set<Status> statusClone = cloner.deepClone(statusList).stream().filter(s -> !(s instanceof FileMetadata)).collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

但是,我还需要设置属性同时过滤它们.过滤后,我目前遍历每个,然后设置属性:

for (Iterator<Status> iterator = statusClone.iterator(); iterator.hasNext();)
        {
            Status s = iterator.next();
//          if (s instanceof FileMetadata)
//          {
//              iterator.remove();
//              continue;
//          }
            s.setStatus(JobStatus.UNINITIATED);
            s.setLastAccessedTime(0);
            s.setOffSet(null);
            s.setStreamNo(null);
        }
        statusList.addAll(statusClone);
Run Code Online (Sandbox Code Playgroud)

如果不使用foreach,这在Java8中是否可行?

编辑:从评论,我同意我可以在过滤器内克隆.谢谢.

ass*_*ias 6

你可以使用peek:

private static void initStatus(Status s) {
  s.setStatus(JobStatus.UNINITIATED);
  s.setLastAccessedTime(0);
  s.setOffSet(null);
  s.setStreamNo(null);
}

Set<Status> statusClone = cloner.deepClone(statusList).stream()
                  .filter(s -> !(s instanceof FileMetadata))
                  .peek(MyClass::initStatus)
                  .collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

请注意,如果您使用并行流,因为您正在修改状态,它可能会产生问题的javadoc警告.


在克隆原始列表时直接初始化状态会更好 - 例如:

private static Status cloneAndInitStatus(Status s) {
  Status clone = new Status(s);
  clone.setStatus(JobStatus.UNINITIATED);
  clone.setLastAccessedTime(0);
  clone.setOffSet(null);
  clone.setStreamNo(null);
  return clone;
}

Set<Status> statusClone = statusList.stream()
                  .filter(s -> !(s instanceof FileMetadata))
                  .map(MyClass::cloneAndInitStatus)
                  .collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

这样就可以避免流中的状态修改.