2016-12-02 2 views
4

Ich möchte die Größe von List nach Element zählen. Zum BeispielZählgröße von Liste nach Element

List<String> source = Arrays.asList("USA", "USA", "Japan", "China", "China", "USA", "USA"); 

Ich mag Objekt (Karte) aus dieser Quelle, wie

int usa_count = result.get("USA").intValue(); // == 4 
int javan_count = result.get("Japan").intValue(); // == 1 
int china_count = result.get("China").intValue(); // == 2 
int uk_count = result.get("UK").intValue(); // == 0 or NPE (both OK) 

Jetzt komponierte ich unten, erstellen.

Map<String, Integer> result = new HashMap<>(); 
for (String str : source) { 
    Integer i = result.getOrDefault(str, Integer.valueOf(0)); 
    result.put(str, i + 1); 
} 

Obwohl, das ist genug, um mein Ziel, ich denke, das ist nicht elegant-Code ist, und ich möchte ein elegant-Codierer sein. Ich benutze Java8. Gibt es eine elegante Lösung anstelle meiner Lösung?

+0

Ich denke, diese Frage passt gut in http://codereview.stackexchange.com/ – NewUser

+2

https://www.mkyong.com/java8/java-8-collectors-groupingby-and-mapping-example/ –

Antwort

2

Sie können die Häufigkeitsmethode in der Sammlung verwenden.

int usa_count = Collections.frequency(source, "USA"); 
int javan_count = Collections.frequency(source, "Japan"); 
int china_count = Collections.frequency(source, "CHINA"); 
int uk_count = Collections.frequency(source, "UK"); 

Siehe: https://www.tutorialspoint.com/java/util/collections_frequency.htm

in Java 8: -

groupingBy Kollektor Gruppe ermöglicht zusammen Elemente, die die gleiche Einteilung in eine Karte.

Map<String, Long> countContries = source.stream().collect(Collectors.groupingBy(Function.identity() , Collectors.counting())); 

Siehe: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html

https://www.mkyong.com/java8/java-8-collectors-groupingby-and-mapping-example/

+3

Dies wird keine Karte obwohl ... –

+1

Btw, können Sie die Javadoc dieser Funktion hinzufügen mache die Antwort nützlicher – Raskayu

2

Sie groupingBy-Streams verwenden können, wie unten dargestellt:

List<String> source = Arrays.asList("USA", "USA", "Japan", 
     "China", "China", "USA", "USA"); 

Map<String, Long> result = 
       source.stream().collect(
         //Use groupingBy 
         Collectors.groupingBy(
           Function.identity(), Collectors.counting() 
         ) 
       ); 


System.out.println(result); 

Ausgang:{USA=4, China=2, Japan=1}

1

Sie können dazu die Stream-API verwenden.

source.stream() 
     .collect(Collectors.groupingBy(
         Function.identity(), 
         Collectors.counting()); 

Die groupingBy -collector erzeugt eine Karte, wo die Schlüssel, die von dem ersten Parameter gegeben sind. Der zweite Parameter kann weggelassen werden, um eine Liste jeder Gruppe zu geben, die denselben Schlüssel hat. In Ihrem Fall, würde dies geben:

Map("USA" -> List("USA", "USA", "USA", "USA"), 
    "Japan" -> List("Japan"), 
    "Chine" -> List("China", China")) 

Durch einen Kollektor als Parameter geben, es wird jede Gruppe sammeln (in diesem Fall die Anzahl der Elemente zu zählen).

0

IMHO Code ist in Ordnung, aber es könnte etwas vereinfacht werden:

Map<String, Integer> result = new HashMap<>(); 
for (String str : source) { 
    int i = result.getOrDefault(str, 0); 
    result.put(str, i + 1); 
} 

oder sogar:

Map<String, Integer> result = new HashMap<>(); 
for (String str : source) { 
    result.put(str, result.getOrDefault(str, 0) + 1); 
} 
Verwandte Themen