1 |
/* HashMap.java -- a class providing a basic hashtable data structure, |
/* HashMap.java -- a class providing a basic hashtable data structure, |
2 |
mapping Object --> Object |
mapping Object --> Object |
3 |
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. |
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. |
4 |
|
|
5 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
6 |
|
|
44 |
* It uses a hash-bucket approach; that is, hash |
* It uses a hash-bucket approach; that is, hash |
45 |
* collisions are handled by linking the new node off of the |
* collisions are handled by linking the new node off of the |
46 |
* pre-existing node (or list of nodes). In this manner, techniques |
* pre-existing node (or list of nodes). In this manner, techniques |
47 |
* such as linear probing (which can casue primary clustering) and |
* such as linear probing (which can cause primary clustering) and |
48 |
* rehashing (which does not fit very well with Java's method of |
* rehashing (which does not fit very well with Java's method of |
49 |
* precomputing hash codes) are avoided. |
* precomputing hash codes) are avoided. |
50 |
* |
* |
51 |
* Under ideal circumstances (no collisions, HashMap offers O(1) |
* Under ideal circumstances (no collisions), HashMap offers O(1) |
52 |
* performance on most operations (<pre>containsValue()</pre> is, |
* performance on most operations (<pre>containsValue()</pre> is, |
53 |
* of course, O(n)). In the worst case (all keys map to the same |
* of course, O(n)). In the worst case (all keys map to the same |
54 |
* hash code -- very unlikely), most operations are O(n). |
* hash code -- very unlikely), most operations are O(n). |
60 |
* @author Jon Zeppieri |
* @author Jon Zeppieri |
61 |
* @author Jochen Hoenicke |
* @author Jochen Hoenicke |
62 |
* @author Bryce McKinlay |
* @author Bryce McKinlay |
63 |
|
* @author Eric Blake <ebb9@email.byu.edu> |
64 |
*/ |
*/ |
65 |
public class HashMap extends AbstractMap |
public class HashMap extends AbstractMap |
66 |
implements Map, Cloneable, Serializable |
implements Map, Cloneable, Serializable |
68 |
/** Default number of buckets. This is the value the JDK 1.3 uses. Some |
/** Default number of buckets. This is the value the JDK 1.3 uses. Some |
69 |
* early documentation specified this value as 101. That is incorrect. */ |
* early documentation specified this value as 101. That is incorrect. */ |
70 |
private static final int DEFAULT_CAPACITY = 11; |
private static final int DEFAULT_CAPACITY = 11; |
71 |
/** The defaulty load factor; this is explicitly specified by the spec. */ |
/** The default load factor; this is explicitly specified by the spec. */ |
72 |
private static final float DEFAULT_LOAD_FACTOR = 0.75f; |
private static final float DEFAULT_LOAD_FACTOR = 0.75f; |
73 |
|
|
74 |
private static final long serialVersionUID = 362498820763181265L; |
private static final long serialVersionUID = 362498820763181265L; |
111 |
{ |
{ |
112 |
super(key, value); |
super(key, value); |
113 |
} |
} |
114 |
|
|
115 |
|
Entry copy() |
116 |
|
{ |
117 |
|
Entry e = new Entry(key, value); |
118 |
|
if (next != null) |
119 |
|
e.next = next.copy(); |
120 |
|
return e; |
121 |
|
} |
122 |
} |
} |
123 |
|
|
124 |
/** |
/** |
141 |
*/ |
*/ |
142 |
public HashMap(Map m) |
public HashMap(Map m) |
143 |
{ |
{ |
144 |
int size = Math.max(m.size() * 2, DEFAULT_CAPACITY); |
this(Math.max(m.size() * 2, DEFAULT_CAPACITY)); |
|
buckets = new Entry[size]; |
|
|
threshold = (int) (size * loadFactor); |
|
145 |
putAll(m); |
putAll(m); |
146 |
} |
} |
147 |
|
|
350 |
public void clear() |
public void clear() |
351 |
{ |
{ |
352 |
modCount++; |
modCount++; |
353 |
for (int i=0; i < buckets.length; i++) |
buckets = new Entry[buckets.length]; |
|
{ |
|
|
buckets[i] = null; |
|
|
} |
|
354 |
size = 0; |
size = 0; |
355 |
} |
} |
356 |
|
|
373 |
for (int i=0; i < buckets.length; i++) |
for (int i=0; i < buckets.length; i++) |
374 |
{ |
{ |
375 |
Entry e = buckets[i]; |
Entry e = buckets[i]; |
376 |
Entry last = null; |
if (e != null) |
377 |
|
copy.buckets[i] = e.copy(); |
|
while (e != null) |
|
|
{ |
|
|
if (last == null) |
|
|
{ |
|
|
copy.buckets[i] = new Entry(e.key, e.value); |
|
|
last = copy.buckets[i]; |
|
|
} |
|
|
else |
|
|
{ |
|
|
last.next = new Entry(e.key, e.value); |
|
|
last = last.next; |
|
|
} |
|
|
e = e.next; |
|
|
} |
|
378 |
} |
} |
379 |
return copy; |
return copy; |
380 |
} |
} |
634 |
// entries. It is null if next() needs to find a new bucket. |
// entries. It is null if next() needs to find a new bucket. |
635 |
Entry next; |
Entry next; |
636 |
|
|
637 |
/* construct a new HashtableIterator with the supllied type: |
/* construct a new HashtableIterator with the supplied type: |
638 |
KEYS, VALUES, or ENTRIES */ |
KEYS, VALUES, or ENTRIES */ |
639 |
HashIterator(int type) |
HashIterator(int type) |
640 |
{ |
{ |