2015-09-01 2 views
8

Ich habe den folgenden Code:Java 8 - Wie Prädikat zu verwenden, das eine Funktion mit Parameter hat?

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; 
    } 
} 

Was ist der richtige Weg, es zu konvertieren Java verwenden 8 Stream s? Wenn ich versuche map() zu verwenden, erhalte ich einen Fehler, da getAttribute kein Function ist.

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

wir einig „Curry“ Ding machen könnten, aber es ist wahrscheinlich nicht wert - 'Curry (:: getAttribute, "style") ' – ZhongYu

Antwort

10

Sie können nicht genau das tun, was Sie wollen - explizite Parameter werden nicht in Verfahren Referenzen erlaubt.

aber man konnte ...

... eine Methode erstellen, die einen Booleschen Wert zurück und harcoded den Anruf zu getAttribute("style"):

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

Dies würde es ermöglichen Sie die Methode ref zu verwenden:

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

... oder Sie können eine Variable definieren, um die Funktion zu halten:

Dies würde erlauben Sie einfach passieren die Variable

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

... oder Sie könnten die beiden oben genannten Ansätze Curry und kombinieren (dies sicherlich furchtbar übertrieben ist)

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

dann würden Sie müssen toAttributeExtractor rufen eine Function und übergeben, daß in den map zu bekommen:

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

Obwohl, realistisch, einfach eine Lambda unter Verwendung einfacher wäre (wie Sie in der nächsten Zeile zu tun):

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

Warum haben Sie all diese peinlichen Lösungen in der Mitte, anstatt am Ende direkt zur Lösung zu gehen? –

+1

@LouisWasserman, weil das OP einen Workaround wollte - ich wollte zeigen, dass die einfache Lösung, die das OP bereits verwendet hat, die beste ist. –

5

Sie können einen Parameter nicht an eine Methodenreferenz übergeben. Sie können einen Lambda-Ausdruck statt:

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

Ich habe mir die Freiheit genommen, den Code so zu formatieren, dass man ihn ohne Scrollen lesen kann. –

+1

@PeterLawrey Danke :) – Eran

Verwandte Themen