java实现top K排序

时间:2022-09-24 19:25:42
后台需要实现对于字段top K排序。需要同时考虑效率和利用成熟代码,尽快实现,首先将字段名,字段出现的次数作为K-V存到map中,然后需要对map进行统计找到出现最多的几个字段。参考
http://www.cnblogs.com/big-sun/p/4085793.html?utm_source=tuicool&utm_medium=referral
采用平衡二叉树对map中出现的次数进行统计,我们是java平台,因此考虑采用成熟的代码直接实现了平衡二叉树。首先想到的就是TreeSet,就采用它实现了。封装了两个类,调用方法如下
TopN top = new TopN(10);//初始化一个排top10的排序类
for(int i=0; i<n; i++){
    top.AddString(String);//将需要排序的所有字符串依次增加到排序类中,
}
Set<TopData> ret = top.getResult();//获取排序结果,结果是递减的
两个相关的类文件如下
public class TopData implements Comparable<TopData> {
    private String name;
    private int score;
    public TopData(String name, int score) {
        this.name = name;
        this.score = score;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    @Override
    public int compareTo(TopData o) {
        // TODO Auto-generated method stub
        if(o.getScore()>this.score){
            return 1;
        }else{
            return -1;
        }
    }
}


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;

public class TopN {
    int m_size;
    TreeSet<TopData> m_topSet = new TreeSet<TopData>();
    Map<String, Integer> m_topMap = new HashMap<String, Integer>();

    public TopN(int top){
        m_size = top;
    }

    //将需要排序的所有字符串依次增加到排序类中
    public void AddString(String key){
        if(m_topMap.containsKey(key)){
            m_topMap.put(key, m_topMap.get(key)+1);
        }else{
            m_topMap.put(key, 1);
        }
    }
    // 将map中的数据top统计到TreeSet中
    protected void MaptoSet(){
        Iterator<Entry<String, Integer>> iterator = m_topMap.entrySet().iterator();
        int temp;
        int minScore = 0xFFFFFFFF;
        while(iterator.hasNext()) {
            Entry<String, Integer> entry = iterator.next();
            temp = entry.getValue();
            if(minScore==0xFFFFFFFF){//第一次运行
                minScore = temp;
            }
            //首先填满m_topSet
            if(m_topSet.size()<m_size){
                m_topSet.add(new TopData(entry.getKey(), entry.getValue()));
                if(temp<minScore){
                    minScore = temp;//更新最低次数
                }
            }else if(temp>minScore){// m_topSet已经填满,并且该次数比最低次数高
                m_topSet.remove(m_topSet.last());//先删除m_topSet中的最低次数的实例
                m_topSet.add(new TopData(entry.getKey(), entry.getValue()));
                minScore = m_topSet.last().getScore();//更新最低次数
            }
        }
    }

    //获取排序结果,结果是递减的
    public Set<TopData> getResult(){
        MaptoSet();
        return m_topSet;
    }
}