2016-06-02 4 views
1

Ist es möglich, Strings über Sammlung während der Gruppierung zu sammeln? Das ist, wie es funktioniert in Java 8:Kann Joiner (Collector, Akkumulator) über die Funktion mit Java Guava angewendet werden?

Map<String, String> discountOptions = p.getDiscountOptions().Stream() 
    .collect(groupingBy(
     this::getDiscountName, 
     Collectors.mapping(this::getValue, Collectors.joining(",")))); 

Ich bin neugierig, gibt es prägnante Art und Weise es in Google Guava zu tun? Das ist, wie ich versuche, es zu replizieren in Guava:

Map<String, Collection<String>> stringCollectionMap = Multimaps.transformValues(
    Multimaps.index(p.getDiscountOptions(), 
     new Function<DiscountOption, String>() { 
      @Override 
      public String apply(DiscountOption d) { 
       return getDiscountName(d); 
      } 
     }), 
    new Function<DiscountOption, String>() { 
     @Override 
     public String apply(DiscountOption d) { 
      return getValue(d); 
     } 
    }).asMap(); 

Map<String, String> discountOptions = Maps.transformValues(
    stringCollectionMap, 
    new Function<Collection<String>, String>() { 
     @Override 
     public String apply(Collection<String> strings) { 
      return Joiner.on(",").join(strings); 
     } 
    }); 
+0

Wenn du sagst "Mach es in Google Guava" meinst du "mach es ohne Java 8 Sprachfunktionen"? Oder warum verwenden Sie für diese funktionalen Schnittstellen keine Lambda-Ausdrücke/Methoden? – Holger

+0

Ja, ohne Java 8 und mein Ziel ist es in imperativer Weise zu tun. –

Antwort

3

Sie sind nicht gehen zu etwas prägnanter als die Java 8 Streams API bekommen, da der Grund, es existiert, ist diese Art von Operationen zu verbessern.

Pre-Java 8 funktionale Programmierung Jury-rigged mit Guava funktionalen Dienstprogramme sein kann, aber as they warn:

Ab Java 7, funktionale Programmierung in Java kann nur durch umständliche und ausführliche Verwendung von anonymen Klassen angenähert wird .... Übermäßige Verwendung der funktionalen Programmierung Idiome der Guava kann ausführlich, verwirrend, unlesbar führen, und ineffiziente Code .... Imperative Code sollte Ihr Standard, Ihre erste Wahl als Java 7.

sein

Hier ist ein Imperativ Übersetzung des Codes:

private static final Joiner COMMA_JOINER = Joiner.on(","); 

ListMultimap<String, String> groupedByDiscountName = ArrayListMultimap.create(); 
for (DiscountOption option : p.getDiscountOptions()) { 
    groupedByDiscountName.put(getDiscountName(option), getValue(option)); 
} 

ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); 
for (Entry<String, Collection<String>> e : groupedByDiscountName.asMap().entrySet()) { 
    builder.put(e.getKey(), COMMA_JOINER.join(e.getValues()); 
} 
Map<String, String> discountOptions = builder.build(); 

Es ist kürzer und leichter zu lesen. In Anbetracht Ihrer aktuellen API ist dies etwa das Beste, was Sie mit Java tun 7.

Das heißt Sie können die erneute Prüfung Ihrer API berücksichtigen - insbesondere ist es seltsam, dass Sie statische Methoden verwenden würde (getDiscountName(), getValue()) Daten zu extrahieren von Ihrer DiscountOption Klasse - diese scheinen klare Kandidaten für Instanzmethoden zu sein. Ähnlich können Sie eine Klasse Discounts erstellen, die eine oder mehrere DiscountOption-Instanzen enthält und eine toString() bereitstellt, die Ihre durch Komma getrennte Zeichenfolge zurückgibt. Dann müssen Sie nur Ihre Objekte konstruieren und Sie sind gut zu gehen.

+0

"Sie werden nichts Konkreteres erhalten als die Java 8-Streams-API", es sei denn, Sie verwenden etwas wie [Kotlin] (https://kotlinlang.org/). Kotlins Bytecode ist kompatibel mit Java 6 und neuer ([FAQ - Kotlin Programmiersprache] (https://kotlinlang.org/docs/reference/faq.html)). – mfulton26

+2

@ mfulton26 lässt die Diskussion zu anderen Sprachen nicht öffnen; es gibt offensichtlich prägnantere Alternativen in knapperen Sprachen. Die Frage betrifft Java und Guava, keine willkürlichen JVM-Sprachen. – dimo414

Verwandte Themen