TopMap
来源:互联网 发布:淘宝怎么拒收退款流程 编辑:程序博客网 时间:2024/05/22 01:12
经常有一种需求,是需要存储键值对,放入一个对象对应的使用次数。
然后需要获取前10%、20%等数据。如果进行Map的全量排序输出会非常慢,因此需要用TreeMap。
使用
TreeMap<Integer,Set<T>>
记录这个调用次数下的对象集合,HashMap<T,Integer>
记录这个对象的调用次数。
在使用时,先查HashMap再在TreeMap中操作数据。
包装后如下:
@Test public void testHashMap() { Map<String, Integer> topMap = new HashMap<>(); List<String> list = new ArrayList<String>(100000); long st = System.currentTimeMillis(); int totalSize = 10000; for (int i = 0; i < totalSize; i++) { String str = null; if (Math.random() > 0.5) { if (list.size() == 0) continue; int choice = (int) (Math.random() * list.size()); str = list.get(choice == list.size() ? choice - 1 : choice); } else { str = UUID.randomUUID().toString(); list.add(str); } if (topMap.containsKey(str)) { topMap.put(str, topMap.get(str) + 1); } else topMap.put(str, 1); } long ed = System.currentTimeMillis(); System.out.println("put data" + (ed - st)); st = System.currentTimeMillis(); for (int i = 0; i < totalSize; i++) { String str = null; if (Math.random() > 0.5) { if (list.size() == 0) continue; int choice = (int) (Math.random() * list.size()); str = list.get(choice == list.size() ? choice - 1 : choice); } else { List<Map.Entry<String, Integer>> list1 = new ArrayList<Map.Entry<String, Integer>>(topMap.entrySet()); Collections.sort(list1, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { return o2.getValue().compareTo(o1.getValue()); } }); } if (topMap.containsKey(str)) { topMap.put(str, topMap.get(str) + 1); } else topMap.put(str, 1); } ed = System.currentTimeMillis(); System.out.println("get data" + (ed - st)); System.out.println(topMap.size() + " "); } @Test public void testSortTreeMap() { //test million data TopMap<String> topMap = new TopMap<String>(); Map<String, Integer> map = new HashMap<>(); List<String> list = new ArrayList<String>(100000); long st = System.currentTimeMillis(); int totalSize = 1000000; for (int i = 0; i < totalSize; i++) { String str = null; if (Math.random() > 0.5) { if (list.size() == 0) continue; int choice = (int) (Math.random() * list.size()); str = list.get(choice == list.size() ? choice - 1 : choice); } else { str = UUID.randomUUID().toString(); list.add(str); } topMap.put(str); } long ed = System.currentTimeMillis(); System.out.println("put data" + (ed - st)); st = System.currentTimeMillis(); for (int i = 0; i < totalSize; i++) { String str = null; if (Math.random() > 0.5) { if (list.size() == 0) continue; int choice = (int) (Math.random() * list.size()); str = list.get(choice == list.size() ? choice - 1 : choice); } else { List<String> list1 = topMap.get(true, 0.001); } if (str != null) topMap.put(str); } ed = System.currentTimeMillis(); System.out.println("get data" + (ed - st)); System.out.println(topMap.size() + " " + topMap.treeSize()); // List<String> list1 = topMap.get(); // for (String s : list1) { // System.out.println(s); // } for (Map.Entry entry : topMap.treeMap.entrySet()) { System.out.println(entry.getKey() + "," + ((Set) (entry.getValue())).size()); } } // public static class TopMap<T> { TreeMap<Integer, Set<T>> treeMap; Map<T, Integer> map; public TopMap() { treeMap = new TreeMap<Integer, Set<T>>(); map = new HashMap<T, Integer>(); } public TopMap(boolean desc) { treeMap = new TreeMap<Integer, Set<T>>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2.compareTo(o1); } }); map = new HashMap<T, Integer>(); } public void put(T key) { int tmp = 0; Set<T> set = null; if (map.containsKey(key)) { tmp = map.get(key); set = treeMap.get(tmp); if (set != null) { set.remove(key); if (set.isEmpty()) treeMap.remove(tmp); } } tmp += 1; map.put(key, tmp); set = treeMap.get(tmp); if (set == null) set = new HashSet<T>(); set.add(key); treeMap.put(tmp, set); } public int treeSize() { return treeMap.size(); } public int size() { return map.size(); } public List<T> get() { return get(treeMap.entrySet()); } public List<T> get(Set<Map.Entry<Integer, Set<T>>> entrySet) { List<T> ret = new LinkedList<T>(); for (Map.Entry<Integer, Set<T>> entry : entrySet) { ret.addAll(entry.getValue()); } return ret; } public List<T> get(double percent) { return get(treeMap.entrySet(), percent); } public List<T> get(boolean desc, double parcent) { if (desc) return get(treeMap.descendingMap().entrySet(), parcent); return get(treeMap.entrySet(), parcent); } public List<T> get(Set<Map.Entry<Integer, Set<T>>> entrySet, double percent) { int capacity = (int) (map.size() * percent); List<T> ret = new LinkedList<T>(); for (Map.Entry<Integer, Set<T>> entry : entrySet) { Set<T> set = entry.getValue(); if (capacity > set.size()) { ret.addAll(set); capacity -= set.size(); } else { for (T t : set) { ret.add(t); if (--capacity <= 0) break; } } if (capacity <= 0) break; } return ret; } }
0 0