简体   繁体   中英

Find most common/frequent element in an ArrayList in Java

I have an array list with 5 elements each of which is an Enum. I want to build a method which returns another array list with the most common element(s) in the list.

Example 1:

[Activities.WALKING, Activities.WALKING, Activities.WALKING, Activities.JOGGING, Activities.STANDING]

Method would return: [Activities.WALKING]

Example 2:

[Activities.WALKING, Activities.WALKING, Activities.JOGGING, Activities.JOGGING, Activities.STANDING]

Method would return: [Activities.WALKING, Activities.JOGGING]

WHAT HAVE I TRIED:

My idea was to declare a count for every activity but that means that if I want to add another activity, I have to go and modify the code to add another count for that activity.

Another idea was to declare a HashMap<Activities, Integer> and iterate the array to insert each activity and its occurence in it. But then how will I extract the Activities with the most occurences?

Can you help me out guys?

The most common way of implementing something like this is counting with a Map : define a Map<MyEnum,Integer> which stores zeros for each element of your enumeration. Then walk through your list, and increment the counter for each element that you find in the list. At the same time, maintain the current max count. Finally, walk through the counter map entries, and add to the output list the keys of all entries the counts of which matches the value of max .

In statistics, this is called the "mode" (in your specific case, "multi mode" is also used , as you want all values that appear most often, not just one). A vanilla Java 8 solution looks like this:

Map<Activities, Long> counts =
Stream.of(WALKING, WALKING, JOGGING, JOGGING, STANDING)
      .collect(Collectors.groupingBy(s -> s, Collectors.counting()));

long max = Collections.max(counts.values());
List<Activities> result = counts
      .entrySet()
      .stream()
      .filter(e -> e.getValue().longValue() == max)
      .map(Entry::getKey)
      .collect(Collectors.toList());

Which yields:

[WALKING, JOGGING]

jOOλ is a library that supports modeAll() on streams. The following program:

System.out.println(
    Seq.of(WALKING, WALKING, JOGGING, JOGGING, STANDING)
       .modeAll()
       .toList()
);

Yields:

[WALKING, JOGGING]

(disclaimer: I work for the company behind jOOλ)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM