【问题标题】:Java nested streamJava 嵌套流
【发布时间】:2016-11-29 14:18:11
【问题描述】:

快速提问: 如何像这样引用嵌套流的父元素:

jpegDir.stream()
    .parallel()
    .map(E -> createDimentionArray(E.getDescription(1), E.getDescription(3)))
    .filter(E -> E != null)
    .forEach(E -> images.stream()
        .filter(J -> J.getType().contains(".jpg"))
        .forEach(I -> I.setSize(E))
    );

最后一个forEach 的父元素E 的类型为string。有没有办法让我在 setSize() 方法中引用 E ?

【问题讨论】:

  • 这应该可以正常工作,你在E的范围内调用setSize
  • 那么它一定是我的代码的其他部分返回了一个空值..
  • 您可以将.peek(System.out::println) 调用添加到您的流中以打印出流中正在处理的值...
  • 请注意,用于返回 createDimentionArray(E.getDescription(1), E.getDescription(3))E 与提供给 forEach 的 lambda 参数不同的 E。它的类型是createDimentionArray的返回类型。这可能是正常的,但是用相同的名字命名不同的东西会令人困惑。
  • 你知道images.stream() .filter(J -> J.getType().contains(".jpg"))的处理结果总是一样的吗?重复这不仅会浪费资源,而且对于通过过滤器的jpegDir 的每个元素多次调用同一对象上的setSize 似乎不是正确的事情。要么,这与意图相去甚远,要么变量和方法的命名方案有问题。

标签: java java-8 java-stream


【解决方案1】:

更新

只是贴出固定的代码,其他人有问题可以看看:

public class Inderxer {

  public void indexFolder(Path path) throws IOException {
      List<Image> images = new LinkedList<>();
       Files.walk(path).parallel().forEach(E -> {
        if (!E.toFile().isDirectory() && !E.toFile().getName().contains(".DS") && FilenameUtils.getExtension(E.toFile().toString()) != ".kmz") {
            try {

                Metadata metadata = ImageMetadataReader.readMetadata(E.toFile());
                if (FilenameUtils.getExtension(E.toFile().toString()).contains("jpg")) {
                    List<Directory> dirs = metadata.getDirectoriesOfType(JpegDirectory.class).stream().collect(Collectors.toList());
                    images.add(new Image(E.getFileName().toString(), FilenameUtils.getExtension(E.toFile().toString()), dirs));
                } else {
                    List<Directory> dirs = metadata.getDirectoriesOfType(PngDirectory.class).stream().collect(Collectors.toList());
                    images.add(new Image(E.getFileName().toString(), FilenameUtils.getExtension(E.toFile().toString()), dirs));
                }

            } catch (ImageProcessingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
    images.stream()
            .forEach(M -> M.getDirectory().stream()
                    .forEach(D -> {
                        if (!M.getType().equals("png")) {
                            M.setSize(createDimentionArray(D.getDescription(1), D.getDescription(3), "jpg"));
                        } else {
                            M.setSize(createDimentionArray(D.getDescription(1), D.getDescription(2), "png"));
                        }
                    }));

    images.forEach(System.out::println);
}

private String createDimentionArray(String h, String w, String type) {
    String res = "";
    if (type.equals("jpg")) {
        if (h != null && w != null) {
            String[] hsplit = h.split("pixels");
            String[] wsplit = w.split("pixels");
            if (hsplit[0] != null && wsplit[0] != null) {
                res = hsplit[0]; //Hight
                res += wsplit[0]; //Width
                res += "\n";
            }
            return res;
        } else {
            return null;
        }

    } else {
        if (h != null && w != null) {
            String[] hsplit = h.split("pixels");
            String[] wsplit = w.split("pixels");
            if (hsplit[0] != null && wsplit[0] != null) {
                res = hsplit[0]; //Hight
                res += " ";
                res += wsplit[0]; //Width
                res += "\n";
            }
            return res;
        } else {
            return null;
        }
    }
  }
}

【讨论】:

  • 哇。这段代码有很多错误。使用equals 比较Strings。在Stream 管道中引入过滤步骤,而不是在foreach 中进行过滤。使用Collector 创建images
  • 另外,不是因为你使用了 lambda,所以你不能再提取方法,试着编写带有意图揭示名称的声明性代码并将事物移动到正确的抽象级别。
  • 这很酷,而且一切都很好。但是,如果你们不喜欢制作粗鲁的 cmets,你们能否用一些如何解决这些“错误”的例子来回答?这样你的 cmets 就变得有建设性了。如果我知道正确的做法,我不会犯这些“错误”。
  • @Lasse 因为这是一个答案而不是问题,所以 cmets 是正确的做法。 cmets 中有几个提示可以解决您的问题。也许你应该阅读一些关于Stream API (official Oracle tutorial) 的教程。也在同一资源"How to compare Strings" 上。教你不是我们的责任。如果你有一个具体的问题,那么你会得到一个具体的答案。
猜你喜欢
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多