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
原创粉丝点击