packageItem;importjava.util.ArrayList;importjava.util.Collections;importjava.util.Comparator;importorg.apache.hadoop.hive.ql.exec.UDAF;importorg.apache.hadoop.hive.ql.exec.UDAFEvaluator;importorg.apache.hadoop.io.IntWritable;public class UDAFTopN extendsUDAF {//定义一个对象用于存储数据
public static classState {public static classTarget{//神经病的,用Text的时候就运行结果不正确
String target;
Double score;publicTarget(){
target= null;
score= null;
}
}public ArrayList list = new ArrayList();private intlimit;
}/*** 累加数据,把要排序的目标和目标值存进map中
*@params 存储对象
*@paramo 待排序目标
*@parami 目标的值*/
private static voidincrement(State s, String o, Double i) {if (s.list == null) {
s.list= new ArrayList();
}
State.Target tmpTarget= newState.Target();
tmpTarget.target=o;
tmpTarget.score=i;
s.list.add(tmpTarget);
tmpTarget= newState.Target();
}public static class UDAFTopNEvaluator implementsUDAFEvaluator {private finalState state;publicUDAFTopNEvaluator() {
state= newState();
}
@Overridepublic voidinit() {if (state.list != null) {
state.list.clear();
}if (state.limit == 0) {
state.limit= 100;
}
}public booleaniterate(String target, Double score, IntWritable limits) {if (target == null || score == null || limits == null) {return false;
}else{
state.limit=limits.get();
increment(state, target, score);
}return true;
}publicState terminatePartial() {returnstate;
}public booleanmerge(State other) {if (state == null || other == null) {return false;
}
state.limit=other.limit;
state.list.addAll(other.list);return true;
}publicString terminate() {if (state == null || state.list.size() == 0) {return null;
}
Collections.sort(state.list,newStatecomparator1());int TopN =state.limit;int size =state.list.size();
StringBuffer str= newStringBuffer();for (int i = 0; i < TopN && i < size; i++) {
str.append(state.list.get(i).target).append(",").append(state.list.get(i).score).append(";");
}return newString(str.toString());
}/** 实现一个list按值的排序算法*/@SuppressWarnings("unchecked")public class Statecomparator1 implements Comparator{public intcompare(Object o1, Object o2){
State.Target s1=(State.Target)o1;
State.Target s2=(State.Target)o2;return s1.score < s2.score ? 1:0;
}
}
}
}