package timeflow.util; import java.util.*; public class DoubleBag<T> implements Iterable<T> { private HashMap<T, Count> table; private double max; public DoubleBag() { table=new HashMap<T, Count>(); } public double getMax() { return max; } public List<T> listTop(int n, boolean useSum) { int count=0; Iterator<T> i=list(useSum).iterator(); List<T> top=new ArrayList<T>(); while (count<n && i.hasNext()) { top.add(i.next()); count++; } return top; } public List<T> list(final boolean useSum) { List<T> result=new ArrayList<T>(); result.addAll(table.keySet()); Collections.sort(result, new Comparator<T>() { public int compare(T x, T y) { double d= useSum ? num(y)-num(x) : average(y)-average(x); return d>0 ? 1 : (d<0 ? -1 : 0); } }); return result; } public double num(T x) { Count c=table.get(x); if (c!=null) return c.num; else return 0; } public double average(T x) { Count c=table.get(x); return c.num/c.vals; } public void add(T x, double z) { if (Double.isNaN(z)) return; Count c=table.get(x); double sum=z; if (c!=null) { c.add(z); sum=c.num; } else { table.put(x, new Count(z)); } max=Math.max(sum, max); } class Count { double num; int vals; public Count(double num) { this.num=num; vals=1; } public double add(double x) { vals++; return num+=x; } } public int size() { return table.size(); } public List<T> unordered() { List<T> result=new ArrayList<T>(); result.addAll(table.keySet()); return result; } public int removeLessThan(int cut) { Set<T> small=new HashSet<T>(); for (T x: table.keySet()) { if (num(x)<cut) small.add(x); } for (T x:small) table.remove(x); return small.size(); } public static void main(String[] args) { DoubleBag<String> b=new DoubleBag<String>(); b.add("a",1); b.add("b",2); b.add("a",3); System.out.println(b.num("a")); System.out.println(b.num("b")); System.out.println(b.num("c")); List<String> s=b.list(true); for (int i=0; i<s.size(); i++) System.out.println(s.get(i)+": "+b.num(s.get(i))); } @Override public Iterator<T> iterator() { return table.keySet().iterator(); } }