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