-3

I've got a problem.

I've got a big Java list of String (about 100K of entry) that contains events name.

It is like this:

List<String> myList =  new ArrayList<>();
myList.add("eventB");
myList.add("eventB");
myList.add("eventA");
myList.add("eventB");
myList.add("eventA");
myList.add("eventA");
myList.add("eventA");
myList.add("eventB");
myList.add("eventB");
myList.add("eventC");
myList.add("eventD");
myList.add("eventC");
...

I need a way to count the occurrences of every event, select the top 1000 events and their occurrences. I don't know all the event's name... I've got about 1000 different event name..

My output should be like this:

                 ___ 
 _________________  |
| EventName |  #  | |
|___________|_____| |
| eventB    | 609 | |
| eventC    | 542 | |
| eventD    | 540 | |
| eventA    | 463 |  \ top 1000
|    .      | .   |  /  entry
|    .      | .   | |
|    .      | .   | |
| eventN    | 123 | |
|___________|_____| |
                 ___|

i need the String of eventName and the Integer of the occurrences (#). (after i 'll put them into a HTML table of a web-application)

i try in this way:

Map<String,Integer> myMap = new HashMap<String, Integer>();
for(String evnt : myList){
    if(!myMap.containsKey(evnt))
        myMap.put(evnt,1);
    else{
        myMap.put(evnt, myMap.get(evnt)+1);
    }
}

But now i don't know how sort it..

Revan1988
  • 121
  • 1
  • 7

4 Answers4

1

Check the following code to store the count of events in map

public static void main(String[] args) {
    List<String> myList = new ArrayList<>();
    myList.add("eventB");
    myList.add("eventB");
    myList.add("eventA");
    myList.add("eventB");
    myList.add("eventA");
    myList.add("eventA");
    myList.add("eventA");
    myList.add("eventA");
    myList.add("eventA");
    myList.add("eventC");
    myList.add("eventD");
    myList.add("eventC");
    Map<String, Integer> countEventMap = new HashMap<String, Integer>();
    for (String event : myList) {
        if (countEventMap.get(event) != null) {
            countEventMap.put(event, countEventMap.get(event) + 1);
        } else
            countEventMap.put(event, 1);
    }

}

Now to get the top 1000 you have to sort based on the values,refer Sorting HashMap by values

To improve the performance you can use concurrency, check this link Data inconsistency using ConcurrentHashMap which you can modify to access the list with each thread starting from particular index and end at some.

Community
  • 1
  • 1
KDP
  • 1,481
  • 7
  • 13
0

Use

Map<Key,List <String>>  

event will be your key

0

Loop through each element, get the string name, add it to a hash map or increment the current value of it by 1.

HashMap<String, Integer> map = new HashMap<String, Integer>();
for  (String s : list) {
    if (map.containsKey(s)) {
        map.put(s, map.get(s) + 1);
    } else {
        map.put(s, 1);
    }
}

May not be the most efficient way but it will work and store them in the way you specified. After that you need to sort it but I'll let you figure that out.

Jmrapp
  • 520
  • 4
  • 13
0

You need to do it in three steps

  1. Count all occurrence of Events.
  2. Sort Events by Value.
  3. Slice top n Events.

Here's the code:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class TopEventCount {

    public static void main(String[] args) {
        List<String> myList = getAllEvents();
        Map<String, Integer> unsortedMap = countEvents(myList);
        System.out.println("Unsorted Map :: " + unsortedMap);
        Map<String, Integer> sortedMap = sortMapByValue(unsortedMap);
        System.out.println("sorted Map :: " + sortedMap);
        
        List<String> topEvents = top(2, sortedMap);
        System.out.println("Top Event :: "+topEvents);
    }

    private static List<String> top(int topElements, Map<String, Integer> sortedMap) {
        List<String> topEvents = new ArrayList<String>();
        Set<String> allEvents = sortedMap.keySet();
        
        Iterator<String> itr = allEvents.iterator();
        int count = 0;
        while(itr.hasNext() && count < topElements) {
            topEvents.add(itr.next());
            count++;
        }
        return topEvents;
    }

    private static Map<String, Integer> sortMapByValue(
            Map<String, Integer> unsortedMap) {
        ValueComparator bvc = new ValueComparator(unsortedMap);
        TreeMap<String, Integer> sortedMap = new TreeMap<String, Integer>(bvc);
        sortedMap.putAll(unsortedMap);
        return sortedMap;
    }

    private static Map<String, Integer> countEvents(List<String> myList) {
        Map<String, Integer> myMap = new HashMap<String, Integer>();
        for (String evnt : myList) {
            if (!myMap.containsKey(evnt))
                myMap.put(evnt, 1);
            else {
                myMap.put(evnt, myMap.get(evnt) + 1);
            }
        }
        return myMap;
    }

    private static List<String> getAllEvents() {
        List<String> myList = new ArrayList<>();
        myList.add("eventB");
        myList.add("eventB");
        myList.add("eventA");
        myList.add("eventB");
        myList.add("eventA");
        myList.add("eventA");
        myList.add("eventA");
        myList.add("eventB");
        myList.add("eventB");
        myList.add("eventC");
        myList.add("eventD");
        myList.add("eventC");
        myList.add("eventE");

        return myList;
    }
}

class ValueComparator implements Comparator<String> {

    Map<String, Integer> base;

    public ValueComparator(Map<String, Integer> base) {
        this.base = base;
    }

    // Note: this comparator imposes orderings that are inconsistent with
    // equals.
    public int compare(String a, String b) {
        if (base.get(a) >= base.get(b)) {
            return -1;
        } else {
            return 1;
        } // returning 0 would merge keys
    }
}

All of the code is self explanatory. Here's the output:

Unsorted Map :: {eventA=4, eventE=1, eventD=1, eventC=2, eventB=5}

sorted Map :: {eventB=5, eventA=4, eventC=2, eventD=1, eventE=1}

Top 2 Event :: [eventB, eventA]

Community
  • 1
  • 1
TheCodingFrog
  • 3,406
  • 3
  • 21
  • 27