2017-08-22 4 views
1

Ich habe eine MultivaluedMap und eine Liste von Zeichenfolgen, und ich möchte sehen, welche dieser Zeichenfolge Schlüssel in der MultivaluedMap sind. Für jede der Zeichenfolgen, die Schlüssel in der MultivaluedMap sind, möchte ich eine neue Thing aus dem Wert dieses Schlüssels erstellen, diese Zeichenfolge als neuen Schlüssel in einer neuen HashMap<String, Thing> setzen und die neue Thing, die ich als erstellt habe Wert für diesen neuen Schlüssel in HashMap.Aggregatliste <String> in HashMap <String, T> mit Stream-API

Gerade jetzt, mit einem Vanille forEach, ich die folgende Arbeitslösung haben:

MultivaluedMap<String, String> params = uriInfo.getQueryParameters(); 
HashMap<String, Thing> result = new HashMap<String, Thing>(); 

listOfStrings.forEach((key) -> { 
    String value = params.getFirst(key); 
    if (value != null && !value.isEmpty()) { 
     result.put(key, new Thing(value)); 
    } 
}); 

Allerdings würde Ich mag eine funktionelle Lösung dieses Problems die Java-Stream-API implementieren und haben eine fews Lösung versucht . Ich habe die folgende, die aussieht wie es sollte funktionieren, aber es funktioniert nicht:

MultivaluedMap<String, String> params = uriInfo.getQueryParameters(); 

HashMap<String, Thing> result = listOfStrings 
     .stream() 
     .filter(params::containsKey) 
     .map(e -> new AbstractMap.SimpleEntry<String, Thing>(e, new Thing(params.getFirst(e)))) 
     .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); 

Die Entry::getKey und Entry::getValue eine „Nicht statische Methode kann nicht von einem statischen Kontext bezeichnet“ geben. Ich habe andere Varianten davon ausprobiert: Konstruieren der Objekte in keyMapper und valueMapper Lambda, und Verwenden von reduzieren mit einer leeren Karte als Anfangswert. Keine hat funktioniert.

Wie würde ich meine erste, funktionierende Lösung mit der Java Stream API und Aggregation (z. B. collect, reduce) umschreiben? Ich habe referiert this Post und this Post und this Post.

+0

Was ist, wenn es auf mehrere Werte abgebildet ist? Auch welche Bibliothek ist 'MultivaluedMap' von? – shmosel

Antwort

1

Ihr Code ist in Ordnung. Sie müssen nur den Rückgabetyp auf Map statt HashMap ändern. Wenn Sie es speziell HashMap benötigen, können Sie HashMap::new in die factory overload übergeben.

Eine Verbesserung, die ich machen würde, ist die unnötige map() Betrieb auszuschneiden und machen die Suche in der Sammler:

Map<String, Thing> result = listOfStrings 
     .stream() 
     .filter(params::containsKey) 
     .collect(Collectors.toMap(Function.identity(), k -> new Thing(params.getFirst(k)))); 
+0

Können Sie erklären, was 'Function.identity()' da macht? – marinatedpork

+1

@marinatedpork Es ist eine Funktion, die ihre Eingabe zurückgibt. Entspricht 'k -> k'. – shmosel

Verwandte Themen