2014-10-17 10 views
31

Mein Wissen über Listen-Operationen ist von Skriptsprachen. Also habe ich in Java auf etwas Seltsames gestoppt, wenn ich einen Cookie mit einem bestimmten Namen gefunden habe.Java 8 zyklische Rückschluss Warnung

List<Cookie> cookies = Arrays.asList(request.getCookies()); 
     String auth = cookies.stream() 
       .filter(c -> c.getName().equals("auth")) 
       .map(Cookie::getValue); 

Auf der map Methode IntelliJ zeigt mir "Cyclic Folgerung".

Java compiler Error:(52, 25) java: incompatible types: no instance(s) of type variable(s) R exist so that java.util.stream.Stream conforms to java.lang.String

+2

Wie die Nachricht sagt, gibt 'map' einen' Stream' zurück und kann keinem 'String' zugewiesen werden. Sie müssen sagen, wie es eine einzelne "String" werden soll. Vielleicht möchten Sie '.findAny(). Get()'? – Holger

+2

Schöne Frage und Antwort, aber ich weiß immer noch nicht, was eine zyklische Schlussfolgerung ist! Werde weiter googeln, das war das erste Ergebnis. – JimLohse

+0

@JimLohse Diese Antwort erklärt, welche zyklische Ableitung ist: http://StackOverflow.com/A/36258012/3142816. Grundsätzlich kann der Typ des inneren Teilausdrucks nicht ohne den Typ des äußeren Teilausdrucks abgeleitet werden, der ohne den Typ des inneren Teilausdrucks nicht abgeleitet werden kann – sorianiv

Antwort

36

Ihr aktueller Code gibt ein Stream<String>, so müssen Sie einen zusätzlichen Schritt eine Zeichenfolge zurück:

Optional<String> auth = cookies.stream() 
      .filter(c -> c.getName().equals("auth")) 
      .map(Cookie::getValue) 
      .findAny(); 

Beachten Sie, dass es ein Optional<String> gibt, weil es keine Plätzchen sein kann, die „Auth“ übereinstimmt. Wenn Sie einen Standard verwendet werden sollen, wenn „Auth“ nicht gefunden ist, können Sie verwenden:

String auth = cookies.stream() 
      .filter(c -> c.getName().equals("auth")) 
      .map(Cookie::getValue) 
      .findAny().orElse(""); 
0

Im Wesentlichen, was diese eher kryptische Fehlermeldung sagt, ist „der Ausgang des Stromfolge nicht übereinstimmt, was Sie zuweisen es am Ende“, z. B.:

String s = list.stream().map(s -> s); // this doesn't result in a String... 

.findFirst() get() so debuggen Kompilierung, entfernen sie die Zuordnung (vorübergehend), oder, wie die andere Antwort sagt, etwas hinzufügen, dass macht es einen String durch das Sammeln zurück (Bsp .: .collect(Collectors.joining(","))) oder (erhalten wie .findFirst().get()), oder ändern Sie die Zuordnung, wie Stream<String> stream = list.stream().map(...)