【问题标题】:Java 8 - How to use predicate that has a function with parameter?Java 8 - 如何使用具有参数函数的谓词?
【发布时间】:2015-09-01 13:03:02
【问题描述】:

我有以下代码:

public boolean isImageSrcExists(String imageSrc) {
    int resultsNum = 0;
    List<WebElement> blogImagesList = driver.findElements(blogImageLocator);

    for (WebElement thisImage : blogImagesList) {
        if (thisImage.getAttribute("style").contains(imageSrc)) {
            resultsNum++;
        }
    }

    if (resultsNum == 2) {
        return true;
    } else {
        return false;
    }
}

将其转换为使用 Java 8 Streams 的正确方法是什么?

当我尝试使用 map() 时,我收到一个错误,因为 getAttribute 不是 Function

int a = (int) blogImagesList.stream()
                            .map(WebElement::getAttribute("style"))
                            .filter(s -> s.contains(imageSrc))
                            .count();

【问题讨论】:

  • 我们可以做一些“咖喱”的东西,但这可能不值得 - curry(::getAttribute, "style")

标签: java lambda java-8 java-stream predicate


【解决方案1】:

您不能完全按照自己的意愿行事 - 方法引用中不允许显式参数。

但你可以...

...创建一个返回布尔值并将调用编码为getAttribute("style")的方法:

public boolean getAttribute(final T t) {
    return t.getAttribute("style");
}

这将允许您使用方法 ref:

int a = (int) blogImagesList.stream()
              .map(this::getAttribute)
              .filter(s -> s.contains(imageSrc))
              .count();

...或者你可以定义一个变量来保存函数:

final Function<T, R> mapper = t -> t.getAttribute("style");

这将允许您简单地传递变量

int a = (int) blogImagesList.stream()
              .map(mapper)
              .filter(s -> s.contains(imageSrc))
              .count();

...或者您可以将上述两种方法结合起来(这肯定是非常过分的)

public Function<T,R> toAttributeExtractor(String attrName) {
    return t -> t.getAttribute(attrName);
}

然后您需要调用toAttributeExtractor 来获取Function 并将其传递给map

final Function<T, R> mapper = toAttributeExtractor("style");
int a = (int) blogImagesList.stream()
              .map(mapper)
              .filter(s -> s.contains(imageSrc))
              .count();

尽管实际上,简单地使用 lambda 会更容易(就像您在下一行中所做的那样):

int a = (int) blogImagesList.stream()
              .map(t -> t.getAttribute("style"))
              .filter(s -> s.contains(imageSrc))
              .count();

【讨论】:

  • 为什么中间有这么多尴尬的解决方案,而不是直接进入最后的解决方案?
  • @LouisWasserman 因为 OP 想要一个解决方法 - 我想说明 OP 已经使用的简单解决方案是最好的。
【解决方案2】:

您不能将参数传递给方法引用。您可以改用 lambda 表达式:

int a = (int) blogImagesList.stream()
                            .map(w -> w.getAttribute("style"))
                            .filter(s -> s.contains(imageSrc))
                            .count();

【讨论】:

  • 我冒昧地对代码进行了格式化,以便您无需滚动即可阅读。
  • @PeterLawrey 谢谢 :)
猜你喜欢
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
相关资源
最近更新 更多