将Jsoup Elements.select()与Optional.ifPresent一起使用

时间:2019-02-27 14:24:53

标签: java jsoup optional

请原谅我的初学者问题。我正在尝试构建网络抓取工具。我制作了一个辅助类Selectors来存储不同类型的CSS选择器,并且该类具有一个getter方法,该方法返回一个可选字段值:

public Optional<String> getName() {
    return Optional.ofNullable(this.name);
}

在我的主Scrapper类中,我有一种方法可以使用Selectors对象从HTML提取名称,如下所示:

public String extractName(Element building) {
    if (this.selectors.getName().isPresent()) {
        String cssSelector = this.selectors.getName().get();
        Elements buildingNameElement = building.select(cssSelector);
        return buildingNameElement.text();
    }
    return "N/A";
}

据我所知,这不是使用Optional类的好方法。但是我正在努力想出一个更好的解决方案。我的第一个念头是使用ifPresent方法,但这种方法不起作用:

public String extractName(Element building) {
    this.selectors.getName().ifPresent(() -> {
        String cssSelector = this.selectors.getName().get();
        Elements buildingNameElement = building.select(cssSelector);
        return buildingNameElement.text();
    });
    return "N/A";
}    

我希望只有在Elements.select()对象中存在名称字段的情况下,Selectors才会执行。谁能帮我使代码更具功能性?

谢谢!

1 个答案:

答案 0 :(得分:0)

public String extractName(Element building) {
     return this.selectors
             .getName()
             .map(cssSelector -> {
                        Elements buildingNameElement = building.select(cssSelector);
                        return buildingNameElement.text();
                    })
             .orElse("N/A");
}  

这就是Optional.map的作用。在Lambda中执行return时,您仅从Lambda返回,而不是从external方法返回。因此,如果getName返回了名称/选择器,则以上内容将使用建筑物名称元素的文本。并返回N/A

如果您可以使用更简洁的语法和更少的命名变量,则可以执行以下操作:

     return this.selectors
             .getName()
             .map(cssSelector -> building.select(cssSelector).text())
             .orElse("N/A");

免责声明:我的计算机上尚未安装JSoup,因此未进行测试。如果有错字,请原谅,然后报告。