2015-10-28 3 views
9

Ich versuche, eine Liste von Doubles in eine Map<Double, Double> zu streamen, wo die Schlüssel die Doubles in der ursprünglichen Liste sind, und die Werte sind einige berechnete Werte. DieseWie konvertiere ich Lambda-Parameter in verwendbare Objekte?

ist, was mein Code wie folgt aussieht:

// "values" is a List<Double> that was passed in 
ImmutableMap<Double, Double> valueMap = values.parallelStream() 
    .collect(Collectors.toMap(p -> p, p -> doThing(values, p))); 

private Double doThing(List<Double>, Double p) { 
    Double computedValue = 0.0; 
    // Do math here with p 
    return computedValue; 
} 

jedoch IntelliJ reklamierte und p -> p ist kein gültiger Lambda-Ausdruck - es geht um eine zyklische Folgerung zu beklagen. Ich bekomme auch einen Fehler, wenn ich doThing aufrufen, weil ein Lambda-Parameter und kein Double ist.

Wenn ich versuche, zu einem Double in den Aufruf an doThing zu werfen, schlägt das fehl, zu übertragen.

Fehle ich etwas wirklich offensichtlich? Es scheint, als ob es keine Möglichkeit gibt, um tatsächlich etwas mit meinen Lambda-Parametern zu tun ...

Antwort

6

Ich denke, das Problem hier ist einfach, dass Ihr Sammelvorgang ein Map<Double, Double> kehrt aber die Art der valueMap ist ImmutableMap<Double, Double>.

Sie haben auch vergessen, einen Namen für die List<Double> Parameter in doThing geben, aber ich nehme an, es war nur ein Tippfehler beim Schreiben der Frage.

+0

Sie haben Recht mit dem Tippfehler, tut mir leid. Es scheint das Problem behoben zu haben, indem man es in eine Map statt in eine UnmableableMap änderte. Weißt du, warum die Fehler, die ich sah, scheinbar nichts miteinander zu tun hatten? Für einen solchen Fehler hätte ich etwas wie einen Typenkonfliktfehler zwischen dem Rückgabewert von .collect() und dem deklarierten Typ von valueMap erwartet. Warum in der Welt würde ein erklärter Typ-Mismatch einen zyklischen Inferenzfehler verursachen ...? – sichinumi

+1

@sichinumi Ich versuchte es mit Eclipse und bekam _Type Mismatch: kann nicht von Map zu ImmutableMap _ konvertieren. Der Fehler, den Sie haben, ist in der Tat ein bisschen komisch. – Bubletan

+2

Afaik, IntelliJ verwendet 'javac' genau wie Netbeans, so kann ich bestätigen, dass Fehlermeldungen, die entweder mit Generics/Type Inference oder Lambda Expressions verbunden sind, verwirrend und weit entfernt vom eigentlichen Problem sein können. Manchmal kann nur ein vergessenes ')', '' 'oder'; 'viele absurde, nicht hilfreiche Fehlermeldungen verursachen. – Holger

1

Wie gesagt, das Problem ist, dass Collectors.toMap das Element in Map<K,U> akkumuliert (die aktuelle Implementierung gibt eine HashMap zurück, aber es ist ein internes Detail).

Wenn Sie in einem ImmutableMap sammeln möchten, können Sie den collectingAndThen Kollektor verwenden.

Verwenden Sie Collectors.toMap als nachgeschalteten Kollektor und bieten Sie die Funktion map -> ImmutableMap.copyOf(map) als Finisher.

ImmutableMap<Double, Double> valueMap = values.stream() 
       .collect(collectingAndThen(toMap(p -> p, p -> doThing(values, p)), ImmutableMap::copyOf)); 
Verwandte Themen