计算列表中String的出现次数,排序并仅提取Java中的前1000个

时间:2015-07-10 14:20:47

标签: java

我遇到了问题。

我有一个包含事件名称的大型Java列表(大约100K条目)。

就像这样:

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

我需要一种方法来计算每个事件的发生次数,选择前1000个事件及其出现次数。我不知道所有活动的名字......我有大约1000个不同的活动名称..

我的输出应该是这样的:

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

我需要eventName的字符串和事件的整数(#)。 (在我将它们放入Web应用程序的HTML表格之后)

我试着这样:

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

但现在我不知道怎么样......

4 个答案:

答案 0 :(得分:1)

检查以下代码以存储地图中的事件数

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

}

现在要获得前1000名,您必须根据值进行排序,请参阅Sorting HashMap by values

要提高性能,您可以使用并发性,请检查此链接Data inconsistency using ConcurrentHashMap,您可以修改该链接以访问列表,每个线程从特定索引开始并以某些结束。

答案 1 :(得分:0)

使用

Map<Key,List <String>>  

事件将是您的关键

答案 2 :(得分:0)

循环遍历每个元素,获取字符串名称,将其添加到哈希映射或将其当前值增加1。

sapply

可能不是最有效的方式,但它可以按照您指定的方式工作和存储。之后你需要对它进行排序,但我会让你弄明白。

答案 3 :(得分:0)

您需要分三步完成

  1. 计算所有事件的发生次数。
  2. 按值排序事件。
  3. Slice top n Events。
  4. 以下是代码:

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

    所有代码都是自我解释的。这是输出:

      

    未排序的地图:: {eventA = 4,eventE = 1,eventD = 1,eventC = 2,eventB = 5}

         

    排序地图:: {eventB = 5,eventA = 4,eventC = 2,eventD = 1,eventE = 1}

         

    Top 2 Event :: [eventB,eventA]