/* * Concept profile generation tool suite * Copyright (C) 2015 Biosemantics Group, Erasmus University Medical Center, * Rotterdam, The Netherlands * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ package org.erasmusmc.collections; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; /** * Class for counting recurring objects. * @author schuemie * * @param <T> */ public class CountingSet<T> implements Set<T>{ public CountingSet(){ key2count = new HashMap<T,Count>(); } public CountingSet(int capacity){ key2count = new HashMap<T,Count>(capacity); } public CountingSet(CountingSet<T> set){ key2count = new HashMap<T,Count>(set.key2count); } public int getCount(T key){ Count count = key2count.get(key); if (count == null) return 0; else return count.count; } /** * Computes the sum of the counts * @return */ public int getSum(){ int sum = 0; for (Count count : key2count.values()) sum += count.count; return sum; } /** * Computes the mean of the counts * @return */ public double getMean(){ return (getSum() / (double)key2count.size()); } /** * Computes the standard deviations of the counts * @return */ public double getSD(){ double mean = getMean(); double sum = 0; for (Count count : key2count.values()) sum += sqr(count.count - mean); return Math.sqrt(sum/(double)key2count.size()); } private double sqr(double d) { return d*d; } public int size() { return key2count.size(); } public boolean isEmpty() { return key2count.isEmpty(); } public boolean contains(Object arg0) { return key2count.containsKey(arg0); } public Iterator<T> iterator() { return key2count.keySet().iterator(); } public Object[] toArray() { return key2count.keySet().toArray(); } @SuppressWarnings("unchecked") public Object[] toArray(Object[] arg0) { return key2count.keySet().toArray(arg0); } public boolean add(T arg0) { Count count = key2count.get(arg0); if (count == null) { count = new Count(); key2count.put(arg0, count); return true; } else { count.count++; return false; } } public boolean add(T arg0, int inc) { Count count = key2count.get(arg0); if (count == null) { count = new Count(); count.count = inc; key2count.put(arg0, count); return true; } else { count.count+= inc; return false; } } public boolean remove(Object arg0) { return (key2count.remove(arg0) != null); } public boolean containsAll(Collection<?> arg0) { return key2count.keySet().containsAll(arg0); } public boolean addAll(Collection<? extends T> arg0) { boolean changed = false; for (T object : arg0){ if (add(object)) changed = true; } return changed; } public boolean retainAll(Collection<?> arg0) { return key2count.keySet().retainAll(arg0); } public boolean removeAll(Collection<?> arg0) { return key2count.keySet().removeAll(arg0); } public void clear() { key2count.clear(); } public Map<T, Count> key2count; public static class Count { public int count = 1; } public void printCounts(){ List<Map.Entry<T, Count>> result = new ArrayList<Map.Entry<T,Count>>(key2count.entrySet()); Collections.sort(result, new Comparator<Map.Entry<T, Count>>(){ public int compare(Entry<T, Count> o1, Entry<T, Count> o2) { return o2.getValue().count - o1.getValue().count; }}); for (Map.Entry<T, Count> entry : result) System.out.println(entry.getKey() + "\t" + entry.getValue().count); } }