KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > jobs > ObjectMap


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.jobs;
12
13 import java.util.*;
14
15 /**
16  * A specialized map implementation that is optimized for a small set of object
17  * keys.
18  *
19  * Implemented as a single array that alternates keys and values.
20  *
21  * Note: This class is copied from org.eclipse.core.resources
22  */

23 public class ObjectMap implements Map {
24     // 8 attribute keys, 8 attribute values
25
protected static final int DEFAULT_SIZE = 16;
26     protected static final int GROW_SIZE = 10;
27     protected int count = 0;
28     protected Object JavaDoc[] elements = null;
29
30     /**
31      * Creates a new object map.
32      *
33      * @param initialCapacity
34      * The initial number of elements that will fit in the map.
35      */

36     public ObjectMap(int initialCapacity) {
37         if (initialCapacity > 0)
38             elements = new Object JavaDoc[Math.max(initialCapacity * 2, 0)];
39     }
40
41     /**
42      * Creates a new object map of the same size as the given map and populate
43      * it with the key/attribute pairs found in the map.
44      *
45      * @param map
46      * The entries in the given map will be added to the new map.
47      */

48     public ObjectMap(Map map) {
49         this(map.size());
50         putAll(map);
51     }
52
53     /**
54      * @see Map#clear()
55      */

56     public void clear() {
57         elements = null;
58         count = 0;
59     }
60
61     /**
62      * @see java.lang.Object#clone()
63      */

64     public Object JavaDoc clone() {
65         return new ObjectMap(this);
66     }
67
68     /**
69      * @see Map#containsKey(java.lang.Object)
70      */

71     public boolean containsKey(Object JavaDoc key) {
72         if (elements == null || count == 0)
73             return false;
74         for (int i = 0; i < elements.length; i = i + 2)
75             if (elements[i] != null && elements[i].equals(key))
76                 return true;
77         return false;
78     }
79
80     /**
81      * @see Map#containsValue(java.lang.Object)
82      */

83     public boolean containsValue(Object JavaDoc value) {
84         if (elements == null || count == 0)
85             return false;
86         for (int i = 1; i < elements.length; i = i + 2)
87             if (elements[i] != null && elements[i].equals(value))
88                 return true;
89         return false;
90     }
91
92     /**
93      * @see Map#entrySet()
94      *
95      * Note: This implementation does not conform properly to the
96      * specification in the Map interface. The returned collection will not
97      * be bound to this map and will not remain in sync with this map.
98      */

99     public Set entrySet() {
100         return toHashMap().entrySet();
101     }
102
103     /**
104      * @see Object#equals(java.lang.Object)
105      */

106     public boolean equals(Object JavaDoc o) {
107         if (!(o instanceof Map))
108             return false;
109         Map other = (Map) o;
110         //must be same size
111
if (count != other.size())
112             return false;
113         //keysets must be equal
114
if (!keySet().equals(other.keySet()))
115             return false;
116         //values for each key must be equal
117
for (int i = 0; i < elements.length; i = i + 2) {
118             if (elements[i] != null && (!elements[i + 1].equals(other.get(elements[i]))))
119                 return false;
120         }
121         return true;
122     }
123
124     /**
125      * @see Map#get(java.lang.Object)
126      */

127     public Object JavaDoc get(Object JavaDoc key) {
128         if (elements == null || count == 0)
129             return null;
130         for (int i = 0; i < elements.length; i = i + 2)
131             if (elements[i] != null && elements[i].equals(key))
132                 return elements[i + 1];
133         return null;
134     }
135
136     /**
137      * The capacity of the map has been exceeded, grow the array by GROW_SIZE to
138      * accomodate more entries.
139      */

140     protected void grow() {
141         Object JavaDoc[] expanded = new Object JavaDoc[elements.length + GROW_SIZE];
142         System.arraycopy(elements, 0, expanded, 0, elements.length);
143         elements = expanded;
144     }
145
146     /**
147      * @see Object#hashCode()
148      */

149     public int hashCode() {
150         int hash = 0;
151         for (int i = 0; i < elements.length; i = i + 2) {
152             if (elements[i] != null) {
153                 hash += elements[i].hashCode();
154             }
155         }
156         return hash;
157     }
158
159     /**
160      * @see Map#isEmpty()
161      */

162     public boolean isEmpty() {
163         return count == 0;
164     }
165
166     /**
167      * Returns all keys in this table as an array.
168      */

169     public String JavaDoc[] keys() {
170         String JavaDoc[] result = new String JavaDoc[count];
171         int next = 0;
172         for (int i = 0; i < elements.length; i = i + 2)
173             if (elements[i] != null)
174                 result[next++] = (String JavaDoc) elements[i];
175         return result;
176     }
177
178     /**
179      * @see Map#keySet()
180      *
181      * Note: This implementation does not conform properly to the
182      * specification in the Map interface. The returned collection will not
183      * be bound to this map and will not remain in sync with this map.
184      */

185     public Set keySet() {
186         Set result = new HashSet(size());
187         for (int i = 0; i < elements.length; i = i + 2) {
188             if (elements[i] != null) {
189                 result.add(elements[i]);
190             }
191         }
192         return result;
193     }
194
195     /**
196      * @see Map#put(java.lang.Object, java.lang.Object)
197      */

198     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
199         if (key == null)
200             throw new NullPointerException JavaDoc();
201         if (value == null)
202             return remove(key);
203
204         // handle the case where we don't have any attributes yet
205
if (elements == null)
206             elements = new Object JavaDoc[DEFAULT_SIZE];
207         if (count == 0) {
208             elements[0] = key;
209             elements[1] = value;
210             count++;
211             return null;
212         }
213
214         int emptyIndex = -1;
215         // replace existing value if it exists
216
for (int i = 0; i < elements.length; i += 2) {
217             if (elements[i] != null) {
218                 if (elements[i].equals(key)) {
219                     Object JavaDoc oldValue = elements[i + 1];
220                     elements[i + 1] = value;
221                     return oldValue;
222                 }
223             } else if (emptyIndex == -1) {
224                 // keep track of the first empty index
225
emptyIndex = i;
226             }
227         }
228         // this will put the emptyIndex greater than the size but
229
// that's ok because we will grow first.
230
if (emptyIndex == -1)
231             emptyIndex = count * 2;
232
233         // otherwise add it to the list of elements.
234
// grow if necessary
235
if (elements.length <= (count * 2))
236             grow();
237         elements[emptyIndex] = key;
238         elements[emptyIndex + 1] = value;
239         count++;
240         return null;
241     }
242
243     /**
244      * @see Map#putAll(java.util.Map)
245      */

246     public void putAll(Map map) {
247         for (Iterator i = map.keySet().iterator(); i.hasNext();) {
248             Object JavaDoc key = i.next();
249             Object JavaDoc value = map.get(key);
250             put(key, value);
251         }
252     }
253
254     /**
255      * @see Map#remove(java.lang.Object)
256      */

257     public Object JavaDoc remove(Object JavaDoc key) {
258         if (elements == null || count == 0)
259             return null;
260         for (int i = 0; i < elements.length; i = i + 2) {
261             if (elements[i] != null && elements[i].equals(key)) {
262                 elements[i] = null;
263                 Object JavaDoc result = elements[i + 1];
264                 elements[i + 1] = null;
265                 count--;
266                 return result;
267             }
268         }
269         return null;
270     }
271
272     /* (non-Javadoc
273      * Method declared on IStringPoolParticipant
274      */

275     public void shareStrings(StringPool set) {
276         //copy elements for thread safety
277
Object JavaDoc[] array = elements;
278         if (array == null)
279             return;
280         for (int i = 0; i < array.length; i++) {
281             Object JavaDoc o = array[i];
282             if (o instanceof String JavaDoc)
283                 array[i] = set.add((String JavaDoc) o);
284         }
285     }
286
287     /**
288      * @see Map#size()
289      */

290     public int size() {
291         return count;
292     }
293
294     /**
295      * Creates a new hash map with the same contents as this map.
296      */

297     private HashMap toHashMap() {
298         HashMap result = new HashMap(size());
299         for (int i = 0; i < elements.length; i = i + 2) {
300             if (elements[i] != null) {
301                 result.put(elements[i], elements[i + 1]);
302             }
303         }
304         return result;
305     }
306
307     /**
308      * @see Map#values()
309      *
310      * Note: This implementation does not conform properly to the
311      * specification in the Map interface. The returned collection will not
312      * be bound to this map and will not remain in sync with this map.
313      */

314     public Collection values() {
315         Set result = new HashSet(size());
316         for (int i = 1; i < elements.length; i = i + 2) {
317             if (elements[i] != null) {
318                 result.add(elements[i]);
319             }
320         }
321         return result;
322     }
323 }
Popular Tags