2016-12-02 93 views
4

我想按元素计数列表的大小。现在 例如,按元素计算列表的大小

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

我想创建从该源对象(MAP),如,

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) 

,我下面组成。

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

尽管这足以达到我的目的,但我认为这不是优雅的代码,我想成为一个优雅的编码器。 我使用Java8。 有没有优雅的解决方案,而不是我的解决方案?

+0

我认为这个问题在合身http://codereview.stackexchange.com/ – NewUser

+2

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

回答

2

您可以在收集中使用频率方法。

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"); 

参见:https://www.tutorialspoint.com/java/util/collections_frequency.htm

爪哇8: -

groupingBy集电极允许组一起具有相同分类到地图元素。

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

参见: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

这不会构造一个地图,虽然... –

+1

顺便说一句,你可以添加该函数的javadoc让答案更有用 – Raskayu

2

您可以使用流groupingBy,如下图所示:

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); 

输出:{USA=4, China=2, Japan=1}

1

您可以使用Stream-api来执行此操作。

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

groupingBy -collector生成一个映射,其中的键由第一个参数给出。第二个参数可以省略,以给出具有相同密钥的每个组的列表。在你的情况,将给予这样的:

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

通过给收集器作为一个参数,它会收集(在这种情况下,计算元素的数量),每个组。

0

恕我直言,你的代码是好的,但也可以稍微简化为:

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

甚至:

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