代码之家  ›  专栏  ›  技术社区  ›  Almas Abdrazak

如何使用流api重写

  •  2
  • Almas Abdrazak  · 技术社区  · 6 年前

    我不知道流api的所有功能。

    我的任务是:我有一个带有url的字符串列表,还有一个带有两个方法的自定义对象列表

    String videoFromUrl(String url);
    
    
    boolean support(String url);
    

    我应该从第一个列表中选择一个由第二个列表的一个实例支持的url,然后返回转换后的url

    我的代码是:

    @Override
        protected String videoSourceFromDocument(final Document document) {
            final List<String> hrefs = ...;
            for (final String href : hrefs) {
                final Optional<VideoDownloader> videoDownloader = this.videoDownloaders/*this is my second list*/
                                                                      .stream()
                                                                      .filter(dwnldr->dwnldr.support(href))
                                                                      .findFirst();
                if(videoDownloader.isPresent()){
                    return videoDownloader.get().videoFromUrl(href);
                }
            }
            this.logger().warn("Url {} doesn't has video source",document.baseUri());
            throw new IllegalArgumentException();
        }
    

    使用流api重写它是更好的方法吗?

    2 回复  |  直到 6 年前
        1
  •  6
  •   JB Nizet    6 年前

    当您需要两个内部循环以命令方式执行某项操作时,使用streams执行相同操作的解决方案通常是使用flatmap:

    protected String videoSourceFromDocument(final Document document) {
        final List<String> hrefs = ...;
        return hrefs.stream()
                    .flatMap(href -> this.videoDownloaders.stream()
                                         .filter(d -> d.support(href))
                                         .map(d -> d.videoFromUrl(href)))
                    .findFirst()
                    .orElseThrow(() -> {
                        this.logger().warn("Url {} doesn't has video source", document.baseUri());
                        return new IllegalArgumentException();
                    });
    }
    

    不过,我会删除日志,并将信息性消息放入illegalargumentexception中。或者直接返回 Optional<String> ,以便来电者可以在没有视频源时决定要执行的操作。

        2
  •  3
  •   Eran    6 年前

    您可以使用一些 Optional 方法:

    return hrefs.stream() // Stream<String>
                .map(href -> this.videoDownloaders
                                 .stream() // Stream<VideoDownloader>
                                 .filter(dwnldr->dwnldr.support(href))
                                 .findFirst() // Optional<VideoDownloader>
                                 .map(dwnldr -> dwnldr.videoFromUrl(href))) // Stream<Optional<String>>
                .filter(Optional::isPresent) // keep only the non-empty Optionals
                .findFirst() // Optional<Optional<String>>
                .orElseThrow(IllegalArgumentException::new) // Optional<String>
                .get(); // String