KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > bsf > debug > util > IntHashtable


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2002 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowlegement may appear in the software itself,
24  * if and wherever such third-party acknowlegements normally appear.
25  *
26  * 4. The names "Apache BSF", "Apache", and "Apache Software Foundation"
27  * must not be used to endorse or promote products derived from
28  * this software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache"
32  * nor may "Apache" appear in their names without prior written
33  * permission of the Apache Group.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many individuals
50  * on behalf of the Apache Software Foundation and was originally created by
51  * Sanjiva Weerawarana and others at International Business Machines
52  * Corporation. For more information on the Apache Software Foundation,
53  * please see <http://www.apache.org/>.
54  */

55
56 package org.apache.bsf.debug.util;
57
58 import java.util.Enumeration JavaDoc;
59 import java.util.NoSuchElementException JavaDoc;
60 /**
61  * Hashtable associates keys with values. Keys and values cannot be null.
62  * The size of the Hashtable is the number of key/value pairs it contains.
63  * The capacity is the number of key/value pairs the Hashtable can hold.
64  * The load factor is a float value which determines how full the Hashtable
65  * gets before expanding the capacity. If the load factor of the Hashtable
66  * is exceeded, the capacity is doubled.
67  *
68  * @author OTI
69  * @version initial
70  *
71  * @see Enumeration
72  * @see java.io.Serializable
73  * @see java.lang.Object#equals
74  * @see java.lang.Object#hashCode
75  */

76
77 public class IntHashtable implements Cloneable JavaDoc {
78   
79   int elementCount;
80   IntHashMapEntry[] elementData;
81   private int loadFactor;
82   private int threshold;
83
84   private static final class HashEnumerator implements Enumeration JavaDoc {
85     IntHashMapEntry array[];
86     int start, end;
87     IntHashMapEntry entry;
88     HashEnumerator (IntHashMapEntry[] entries) {
89       array = entries;
90       start = 0;
91       end = array.length;
92     }
93     public boolean hasMoreElements () {
94       if (entry != null) return true;
95       while (start < end) {
96         if (array[start] == null) start++;
97         else return true;
98       }
99       return false;
100     }
101     public Object JavaDoc nextElement () {
102       if (hasMoreElements()) {
103         if (entry == null) entry = array[start++];
104         Object JavaDoc result = entry.value;
105         entry = entry.next;
106         return result;
107       }
108       throw new NoSuchElementException JavaDoc();
109     }
110   }
111
112   /**
113   * Constructs a new Hashtable using the default capacity
114   * and load factor.
115   *
116   * @author OTI
117   * @version initial
118   */

119   public IntHashtable() {
120   this (101);
121   }
122   /**
123   * Constructs a new IntHashtable using the specified capacity
124   * and the default load factor.
125   *
126   * @author OTI
127   * @version initial
128   *
129   * @param capacity the initial capacity
130   */

131   public IntHashtable(int capacity) {
132   if (capacity < 0) throw new IllegalArgumentException JavaDoc();
133   elementCount = 0;
134   elementData = new IntHashMapEntry[capacity == 0 ? 1 : capacity];
135   loadFactor = 7500; // Default load factor of 0.75
136
computeMaxSize();
137   }
138   /**
139   * Constructs a new IntHashtable using the specified capacity
140   * and load factor.
141   *
142   * @author OTI
143   * @version initial
144   *
145   * @param capacity the initial capacity
146   * @param loadFactor the initial load factor
147   */

148   public IntHashtable(int capacity, float loadFactor) {
149   if (capacity < 0 || loadFactor <= 0)
150   throw new IllegalArgumentException JavaDoc();
151   elementCount = 0;
152   elementData = new IntHashMapEntry[capacity];
153   this.loadFactor = (int)(loadFactor * 10000);
154   computeMaxSize();
155   }
156   /**
157    * Removes all key/value pairs from this IntHashtable, leaving the size zero
158    * and the capacity unchanged.
159    *
160    * @author OTI
161    * @version initial
162    *
163    * @see #isEmpty
164    * @see #size
165    */

166   public synchronized void clear() {
167     elementCount = 0;
168     for (int i = elementData.length; --i >= 0;) {
169       elementData[i] = null;
170     }
171   }
172   /**
173    * Answers a new IntHashtable with the same key/value pairs, capacity
174    * and load factor.
175    *
176    * @author OTI
177    * @version initial
178    *
179    * @return a shallow copy of this IntHashtable
180    *
181    * @see java.lang.Cloneable
182    */

183   public synchronized Object JavaDoc clone() {
184     try {
185       IntHashtable hashtable = (IntHashtable) super.clone ();
186       hashtable.elementData = (IntHashMapEntry[])elementData.clone();
187       IntHashMapEntry entry;
188       for (int i=elementData.length; --i >= 0;) {
189         if ((entry = elementData[i]) != null)
190           hashtable.elementData[i] = (IntHashMapEntry)entry.clone();
191       }
192       return hashtable;
193     } catch (CloneNotSupportedException JavaDoc e) {
194         return null;
195     }
196   }
197   private void computeMaxSize() {
198     threshold = (int)((long)elementData.length * loadFactor / 10000);
199   }
200   /**
201    * Answers if this Hashtable contains the specified object as the value
202    * of at least one of the key/value pairs.
203    *
204    * @author OTI
205    * @version initial
206    *
207    * @param value the object to look for as a value in this Hashtable
208    * @return true if object is a value in this Hashtable, false otherwise
209    *
210    * @see #containsKey
211    * @see java.lang.Object#equals
212    */

213   public synchronized boolean contains(Object JavaDoc value) {
214     for (int i=elementData.length; --i >= 0;) {
215       IntHashMapEntry entry = elementData[i];
216       while (entry != null) {
217         if (entry.value == value || entry.value.equals(value))
218           return true;
219         entry = entry.next;
220       }
221     }
222     return false;
223   }
224   /**
225    * Answers if this Hashtable contains the specified object as a key
226    * of one of the key/value pairs.
227    *
228    * @author OTI
229    * @version initial
230    *
231    * @param key the object to look for as a key in this Hashtable
232    * @return true if object is a key in this Hashtable, false otherwise
233    *
234    * @see #contains
235    * @see java.lang.Object#equals
236    */

237   public synchronized boolean containsKey(int key) {
238     return getEntry(key) != null;
239   }
240   /**
241    * Answers an Enumeration on the values of this Hashtable. The
242    * results of the Enumeration may be affected if the contents
243    * of this Hashtable are modified.
244    *
245    * @author OTI
246    * @version initial
247    *
248    * @return an Enumeration of the values of this Hashtable
249    *
250    * @see #keys
251    * @see #size
252    * @see Enumeration
253    */

254   public synchronized Enumeration JavaDoc elements() {
255     return new HashEnumerator (elementData);
256   }
257   /**
258    * Answers the value associated with the specified key in
259    * this Hashtable.
260    *
261    * @author OTI
262    * @version initial
263    *
264    * @param key the key of the value returned
265    * @return the value associated with the specified key, null if the specified key
266    * does not exist
267    *
268    * @see #put
269    */

270   public synchronized Object JavaDoc get(int key) {
271     int index = (key & 0x7FFFFFFF) % elementData.length;
272     IntHashMapEntry entry = elementData[index];
273     while (entry != null) {
274       if (entry.key == key) return entry.value;
275       entry = entry.next;
276     }
277     return null;
278   }
279   private IntHashMapEntry getEntry(int key) {
280     int index = (key & 0x7FFFFFFF) % elementData.length;
281     IntHashMapEntry entry = elementData[index];
282     while (entry != null) {
283       if (entry.key == key) return entry;
284       entry = entry.next;
285     }
286     return null;
287   }
288   /**
289    * Answers if this Hashtable has no key/value pairs, a size of zero.
290    *
291    * @author OTI
292    * @version initial
293    *
294    * @return true if this Hashtable has no key/value pairs, false otherwise
295    *
296    * @see #size
297    */

298   public boolean isEmpty() {
299     return elementCount == 0;
300   }
301   /**
302    * Associate the specified value with the specified key in this Hashtable.
303    * If the key already exists, the old value is replaced. The key and value
304    * cannot be null.
305    *
306    * @author OTI
307    * @version initial
308    *
309    * @param key the key to add
310    * @param value the value to add
311    * @return the old value associated with the specified key, null if the key did
312    * not exist
313    *
314    * @see #elements
315    * @see #get
316    * @see #keys
317    * @see java.lang.Object#equals
318    */

319   public synchronized Object JavaDoc put(int key, Object JavaDoc value) {
320     if (value == null) throw new NullPointerException JavaDoc ();
321     int index = (key & 0x7FFFFFFF) % elementData.length;
322     IntHashMapEntry entry = elementData[index];
323     while (entry != null) {
324       if (entry.key == key) break;
325       entry = entry.next;
326     }
327     if (entry == null) {
328       if (++elementCount > threshold) {
329         rehash();
330         index = (key & 0x7FFFFFFF) % elementData.length;
331       }
332       entry = new IntHashMapEntry(key, value);
333       entry.next = elementData[index];
334       elementData[index] = entry;
335       return null;
336     }
337     Object JavaDoc result = entry.value;
338     entry.value = value;
339     return result;
340   }
341   /**
342    * Increases the capacity of this Hashtable. This method is sent when
343    * the size of this Hashtable exceeds the load factor.
344    *
345    * @author OTI
346    * @version initial
347    */

348   protected void rehash() {
349     int length = elementData.length<<1;
350     if (length == 0) length = 1;
351     IntHashMapEntry[] newData = new IntHashMapEntry[length];
352     for (int i=elementData.length; --i >= 0;) {
353       IntHashMapEntry entry = elementData[i];
354       while (entry != null) {
355         int index = (entry.key & 0x7FFFFFFF) % length;
356         IntHashMapEntry next = entry.next;
357         entry.next = newData[index];
358         newData[index] = entry;
359         entry = next;
360       }
361     }
362     elementData = newData;
363     computeMaxSize();
364   }
365   /**
366    * Remove the key/value pair with the specified key from this Hashtable.
367    *
368    * @author OTI
369    * @version initial
370    *
371    * @param key the key to remove
372    * @return the value associated with the specified key, null if the specified key
373    * did not exist
374    *
375    * @see #get
376    * @see #put
377    */

378   public synchronized Object JavaDoc remove(int key) {
379     IntHashMapEntry last = null;
380     int index = (key & 0x7FFFFFFF) % elementData.length;
381     IntHashMapEntry entry = elementData[index];
382     while (entry != null) {
383       if (entry.key == key) break;
384       last = entry;
385       entry = entry.next;
386     }
387     if (entry != null) {
388       if (last == null) elementData[index] = entry.next;
389       else last.next = entry.next;
390       elementCount--;
391       return entry.value;
392     }
393     return null;
394   }
395   /**
396    * Answers the number of key/value pairs in this Hashtable.
397    *
398    * @author OTI
399    * @version initial
400    *
401    * @return the number of key/value pairs in this Hashtable
402    *
403    * @see #elements
404    * @see #keys
405    */

406   public int size() {
407     return elementCount;
408   }
409   /**
410    * Answers the string representation of this Hashtable.
411    *
412    * @author OTI
413    * @version initial
414    *
415    * @return the string representation of this Hashtable
416    */

417   public synchronized String JavaDoc toString() {
418     Object JavaDoc key;
419     int count = 0;
420     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc ();
421     buffer.append ('{');
422     for (int i=elementData.length; --i >= 0;) {
423       IntHashMapEntry entry = elementData[i];
424       while (entry != null) {
425         buffer.append(entry.key);
426         buffer.append('=');
427         buffer.append(entry.value);
428         buffer.append(',');
429         entry = entry.next;
430       }
431     }
432     // Remove the last ','
433
if (elementCount > 0) buffer.setLength(buffer.length() - 1);
434     buffer.append ('}');
435     return buffer.toString ();
436   }
437 }
438
Popular Tags