Java tutorial
/* StatCvs - CVS statistics generation Copyright (C) 2002 Lukasz Pekacki <lukasz@pekacki.de> http://statcvs.sf.net/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Name: $ Created on $Date: 2008/04/02 11:52:02 $ */ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * Utility class for storing a map from <code>Object</code>s to * <code>int</code>s. * This class makes it easy to sort by key or value, and provides * useful features like {@link #sum()}, {@link #max()}, and * percent calculation. * <p> * The keys must be comparable, for example <code>String</code>s. * <p> * Behaviour for <code>null</code> keys is unspecified. * * @author Richard Cyganiak * @version $Id: IntegerMap.java,v 1.16 2008/04/02 11:52:02 benoitx Exp $ */ public class IntegerMap { private final Map map = new TreeMap(); private final Comparator comparator = new SortByValueComparator(map); private int sum = 0; private int max = 0; /** * Puts a value into the map, overwriting any previous value * for the same key. * * @param key an <code>Object</code> which is used as key. * @param value the <code>int</code> value to be stored at this key. */ public void put(final Object key, final int value) { max = Math.max(max, value); sum -= get(key); sum += value; map.put(key, new Integer(value)); } /** * Gets a value from the map. Returns the value which was * stored in the map at the same key before. If no value was * stored for this key, 0 will be returned. * * @param key an <code>Object</code> which is used as key. * @return the value for this key */ public int get(final Object key) { final Integer result = (Integer) map.get(key); if (result == null) { return 0; } return result.intValue(); } /** * Same as {@link #get(Object)}, but returns an <code>Integer</code>, * not an <code>int</code>. * * @param key the key to get the value for * @return the value wrapped in an <code>Integer</code> object */ public Integer getInteger(final Object key) { return (Integer) map.get(key); } /** * Gets the value stored at a key as a percentage of all values * in the map. * * @param key the key to get the value for * @return the value as a percentage of the sum of all values */ public double getPercent(final Object key) { return (double) get(key) * 100 / sum; } /** * Gets the value stored at a key as a percentage of the maximum * value in the map. For the maximum value, this will return * 100.0. For a value half as large as the maximum value, this * will return 50.0. * * @param key the key to get the value for * @return the value as a percentage of largest value in the map */ public double getPercentOfMaximum(final Object key) { return get(key) * 100 / max; } /** * Adds an <code>int</code> to the value stored at a key. * If no value was stored before at this key, the <code>int</code> * will be stored there. * * @param key the key to whose value <code>addValue</code> should be added * @param addValue the <code>int</code> to be added */ public void addInt(final Object key, final int addValue) { put(key, addValue + get(key)); } /** * Same as <code>addInt(key, 1)</code> * * @param key the key whose value should be increased */ public void inc(final Object key) { addInt(key, 1); } /** * Same as <code>addInt(key, -1)</code> * * @param key the key whose value should be decreased */ public void dec(final Object key) { addInt(key, -1); } /** * Deletes a value from the map. This is different from * <code>put(key, 0)</code>. Removing will reduce * the size of the map, putting 0 will not. * * @param key the key that should be removed */ public void remove(final Object key) { sum -= get(key); map.remove(key); } /** * Returns <code>true</code> if the map contains a value * for this key. * * @param key the key to check for * @return <code>true</code> if the key is in the map */ public boolean contains(final Object key) { return map.containsKey(key); } /** * Returns the number of key-value pairs stored in the map. * * @return the number of key-value pairs stored in the map */ public int size() { return map.size(); } /** * Returns a set view of the keys. The set will be in * ascending key order. * * @return a <code>Set</code> view of all keys */ public Set keySet() { return map.keySet(); } /** * Returns an iterator on the keys, sorted by key ascending. * * @return an iterator on the keys */ public Iterator iteratorSortedByKey() { return map.keySet().iterator(); } /** * Returns an iterator on the keys, sorted by values ascending. * * @return an iterator on the keys */ public Iterator iteratorSortedByValue() { final List keys = new ArrayList(map.keySet()); Collections.sort(keys, comparator); return keys.iterator(); } /** * Returns an iterator on the keys, sorted by values descending. * * @return an iterator on the keys */ public Iterator iteratorSortedByValueReverse() { final List keys = new ArrayList(map.keySet()); Collections.sort(keys, comparator); Collections.reverse(keys); return keys.iterator(); } /** * Returns the sum of all values in the map. * * @return the sum of all values in the map */ public int sum() { return sum; } /** * Returns the average of all values in the map. * * @return the average of all values in the map */ public double average() { return (double) sum() / size(); } /** * Returns the maximum value in the map. * * @return the maximum value in the map. */ public int max() { return max; } /** * Private utility class for comparing of map entries by value. */ private static class SortByValueComparator implements Comparator { private final Map mapToBeSorted; public SortByValueComparator(final Map map) { this.mapToBeSorted = map; } public int compare(final Object o1, final Object o2) { final int i1 = ((Integer) this.mapToBeSorted.get(o1)).intValue(); final int i2 = ((Integer) this.mapToBeSorted.get(o2)).intValue(); if (i1 < i2) { return -1; } else if (i1 > i2) { return 1; } return 0; } } }