Item Count Size

I would like to count the size of a list by an element. For instance,

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

I would like to create an object (Map) from this source, for example

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)

Now I wrote below.

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

Although this is enough for my purpose, I think this is not elegant code, and I want to be an elegant encoder. I am using Java8. Is there an elegant solution instead of my solution?

+4
source share
4 answers

You can use the frequency method in the collection.

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

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

in Java 8 : -

groupingBy collector allows you to group items that have the same classification into a map.

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/

+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}

+2

You can use Stream-api for this.

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

groupingBy-collector generates a map where the keys are specified by the first parameter. The second parameter can be omitted to indicate a list of each group with the same key. In your case, this will give the following:

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

Providing the collector as a parameter, he will collect each group (in this case, counting the number of elements).

+1
source

IMHO, your code is fine, but it can be simplified a bit:

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

or even:

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

Source: https://habr.com/ru/post/1662604/


All Articles