Coverage Report - net.sf.statcvs.util.IntegerMap
 
Classes in this File Line Coverage Branch Coverage Complexity
IntegerMap
59%
37/63
50%
2/4
1.3
IntegerMap$SortByValueComparator
69%
9/13
38%
3/8
1.3
 
 1  
 /*
 2  
     StatCvs - CVS statistics generation 
 3  
     Copyright (C) 2002  Lukasz Pekacki <lukasz@pekacki.de>
 4  
     http://statcvs.sf.net/
 5  
     
 6  
     This library is free software; you can redistribute it and/or
 7  
     modify it under the terms of the GNU Lesser General Public
 8  
     License as published by the Free Software Foundation; either
 9  
     version 2.1 of the License, or (at your option) any later version.
 10  
 
 11  
     This library is distributed in the hope that it will be useful,
 12  
     but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  
     Lesser General Public License for more details.
 15  
 
 16  
     You should have received a copy of the GNU Lesser General Public
 17  
     License along with this library; if not, write to the Free Software
 18  
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 19  
     
 20  
         $Name:  $ 
 21  
         Created on $Date: 2009/08/20 17:44:05 $ 
 22  
 */
 23  
 package net.sf.statcvs.util;
 24  
 
 25  
 import java.io.Serializable;
 26  
 import java.util.ArrayList;
 27  
 import java.util.Collections;
 28  
 import java.util.Comparator;
 29  
 import java.util.Iterator;
 30  
 import java.util.List;
 31  
 import java.util.Map;
 32  
 import java.util.Set;
 33  
 import java.util.TreeMap;
 34  
 
 35  
 /**
 36  
  * Utility class for storing a map from <code>Object</code>s to
 37  
  * <code>int</code>s.
 38  
  * This class makes it easy to sort by key or value, and provides
 39  
  * useful features like {@link #sum()}, {@link #max()}, and
 40  
  * percent calculation.
 41  
  * <p>
 42  
  * The keys must be comparable, for example <code>String</code>s.
 43  
  * <p>
 44  
  * Behaviour for <code>null</code> keys is unspecified.
 45  
  * 
 46  
  * @author Richard Cyganiak
 47  
  * @version $Id: IntegerMap.java,v 1.17 2009/08/20 17:44:05 benoitx Exp $
 48  256
  */
 49  0
 public class IntegerMap {
 50  256
 
 51  256
     private final Map map = new TreeMap();
 52  256
     private final Comparator comparator = new SortByValueComparator(map);
 53  256
     private int sum = 0;
 54  0
     private int max = 0;
 55  
 
 56  
     /**
 57  
      * Puts a value into the map, overwriting any previous value
 58  
      * for the same key.
 59  
      * 
 60  
      * @param key an <code>Object</code> which is used as key.
 61  
      * @param value the <code>int</code> value to be stored at this key.
 62  
      */
 63  512
     public void put(final Object key, final int value) {
 64  512
         max = Math.max(max, value);
 65  512
         sum -= get(key);
 66  512
         sum += value;
 67  512
         map.put(key, new Integer(value));
 68  0
     }
 69  
 
 70  
     /**
 71  
      * Gets a value from the map. Returns the value which was
 72  
      * stored in the map at the same key before. If no value was
 73  
      * stored for this key, 0 will be returned.
 74  
      * 
 75  
      * @param key an <code>Object</code> which is used as key.
 76  
      * @return the value for this key
 77  
      */
 78  808
     public int get(final Object key) {
 79  808
         final Integer result = (Integer) map.get(key);
 80  584
         if (result == null) {
 81  0
             return 0;
 82  224
         }
 83  0
         return result.intValue();
 84  
     }
 85  
 
 86  
     /**
 87  
      * Same as {@link #get(Object)}, but returns an <code>Integer</code>,
 88  
      * not an <code>int</code>.
 89  
      * 
 90  
      * @param key the key to get the value for
 91  
      * @return the value wrapped in an <code>Integer</code> object
 92  
      */
 93  24
     public Integer getInteger(final Object key) {
 94  0
         return (Integer) map.get(key);
 95  
     }
 96  
 
 97  
     /**
 98  
      * Gets the value stored at a key as a percentage of all values
 99  
      * in the map.
 100  
      * 
 101  
      * @param key the key to get the value for
 102  
      * @return the value as a percentage of the sum of all values
 103  
      */
 104  48
     public double getPercent(final Object key) {
 105  0
         return (double) get(key) * 100 / sum;
 106  
     }
 107  
 
 108  
     /**
 109  
      * Gets the value stored at a key as a percentage of the maximum
 110  
      * value in the map. For the maximum value, this will return
 111  
      * 100.0. For a value half as large as the maximum value, this
 112  
      * will return 50.0.
 113  
      * 
 114  
      * @param key the key to get the value for
 115  
      * @return the value as a percentage of largest value in the map
 116  
      */
 117  32
     public double getPercentOfMaximum(final Object key) {
 118  0
         return get(key) * 100 / (double) max;
 119  
     }
 120  
 
 121  
     /**
 122  
      * Adds an <code>int</code> to the value stored at a key.
 123  
      * If no value was stored before at this key, the <code>int</code>
 124  
      * will be stored there.
 125  
      * 
 126  
      * @param key the key to whose value <code>addValue</code> should be added
 127  
      * @param addValue the <code>int</code> to be added
 128  
      */
 129  104
     public void addInt(final Object key, final int addValue) {
 130  104
         put(key, addValue + get(key));
 131  0
     }
 132  
 
 133  
     /**
 134  
      * Same as <code>addInt(key, 1)</code>
 135  
      * 
 136  
      * @param key the key whose value should be increased
 137  
      */
 138  0
     public void inc(final Object key) {
 139  0
         addInt(key, 1);
 140  0
     }
 141  
 
 142  
     /**
 143  
      * Same as <code>addInt(key, -1)</code>
 144  
      * 
 145  
      * @param key the key whose value should be decreased
 146  
      */
 147  0
     public void dec(final Object key) {
 148  0
         addInt(key, -1);
 149  0
     }
 150  
 
 151  
     /**
 152  
      * Deletes a value from the map. This is different from
 153  
      * <code>put(key, 0)</code>. Removing will reduce
 154  
      * the size of the map, putting 0 will not.
 155  
      * 
 156  
      * @param key the key that should be removed
 157  
      */
 158  24
     public void remove(final Object key) {
 159  24
         sum -= get(key);
 160  24
         map.remove(key);
 161  0
     }
 162  
 
 163  
     /**
 164  
      * Returns <code>true</code> if the map contains a value
 165  
      * for this key.
 166  
      * 
 167  
      * @param key the key to check for
 168  
      * @return <code>true</code> if the key is in the map
 169  
      */
 170  120
     public boolean contains(final Object key) {
 171  0
         return map.containsKey(key);
 172  
     }
 173  
 
 174  
     /**
 175  
      * Returns the number of key-value pairs stored in the map.
 176  
      * 
 177  
      * @return the number of key-value pairs stored in the map
 178  
      */
 179  64
     public int size() {
 180  0
         return map.size();
 181  
     }
 182  
 
 183  
     /**
 184  
      * Returns a set view of the keys. The set will be in
 185  
      * ascending key order.
 186  
      * 
 187  
      * @return a <code>Set</code> view of all keys
 188  
      */
 189  16
     public Set keySet() {
 190  0
         return map.keySet();
 191  
     }
 192  
 
 193  
     /**
 194  
      * Returns an iterator on the keys, sorted by key ascending.
 195  
      * 
 196  
      * @return an iterator on the keys
 197  
      */
 198  128
     public Iterator iteratorSortedByKey() {
 199  0
         return map.keySet().iterator();
 200  
     }
 201  
 
 202  
     /**
 203  
      * Returns an iterator on the keys, sorted by values ascending.
 204  
      * 
 205  
      * @return an iterator on the keys
 206  
      */
 207  16
     public Iterator iteratorSortedByValue() {
 208  16
         final List keys = new ArrayList(map.keySet());
 209  16
         Collections.sort(keys, comparator);
 210  0
         return keys.iterator();
 211  
     }
 212  
 
 213  
     /**
 214  
      * Returns an iterator on the keys, sorted by values descending.
 215  
      * 
 216  
      * @return an iterator on the keys
 217  
      */
 218  16
     public Iterator iteratorSortedByValueReverse() {
 219  16
         final List keys = new ArrayList(map.keySet());
 220  16
         Collections.sort(keys, comparator);
 221  16
         Collections.reverse(keys);
 222  0
         return keys.iterator();
 223  
     }
 224  
 
 225  
     /**
 226  
      * Returns the sum of all values in the map.
 227  
      * 
 228  
      * @return the sum of all values in the map
 229  
      */
 230  48
     public int sum() {
 231  0
         return sum;
 232  
     }
 233  
 
 234  
     /**
 235  
      * Returns the average of all values in the map.
 236  
      * 
 237  
      * @return the average of all values in the map
 238  
      */
 239  16
     public double average() {
 240  0
         return (double) sum() / size();
 241  
     }
 242  
 
 243  
     /**
 244  
      * Returns the maximum value in the map.
 245  
      * 
 246  
      * @return the maximum value in the map.
 247  
      */
 248  16
     public int max() {
 249  0
         return max;
 250  
     }
 251  
 
 252  
     /**
 253  
      * Private utility class for comparing of map entries by value.
 254  256
      */
 255  0
     private static class SortByValueComparator implements Comparator, Serializable {
 256  
         private final Map mapToBeSorted;
 257  256
 
 258  256
         public SortByValueComparator(final Map map) {
 259  256
             this.mapToBeSorted = map;
 260  0
         }
 261  
 
 262  192
         public int compare(final Object o1, final Object o2) {
 263  192
             final int i1 = ((Integer) this.mapToBeSorted.get(o1)).intValue();
 264  192
             final int i2 = ((Integer) this.mapToBeSorted.get(o2)).intValue();
 265  48
             if (i1 < i2) {
 266  144
                 return -1;
 267  144
             } else if (i1 > i2) {
 268  0
                 return 1;
 269  0
             }
 270  0
             return 0;
 271  
         }
 272  
     }
 273  
 }