Reputation: 33
Hashtable ht = new Hashtable();
for (int i = 0; i < 100; i++) {
ht.put(i%10, i);
}
Enumeration< Integer> eles = ht.elements();
while(eles.hasMoreElements())
System.out.println(eles.nextElement());
Above code snippet is printing 99, 98,.......90
But I want to print all 100 elements. How to get a list of numbers like ... 99,89,79,69,...19,9 98,88,78,68....18,8 97,87,77,67....17,7 .. .. 91,81,71,61....11,1
Basically all collision list.
Upvotes: 0
Views: 429
Reputation: 4024
What you observe in your example is not collision effect. It is normal element replacement. After your 100 iteration there are only 10 elements in Hashtable.
You use numbers i%10 (0,1,...,9) as keys. So, you have only 10 different keys. For example: in your for-loop you put 10 values for key=5 (i=5, i=15, i=95) and each put(5, val) replaces old value associated with key=5.
Collision list is different concept.
For each key hashtable computes some hash value and uses this hash to select index in its inner bucket table. Next places {key,value} under that index. Collision is situation where 2 different keys has computed the same bucket index.
For example:
table index | map.entry
0 | {0, "A"}
1 | {3, "B"}
2 | {2, "A"} -> {4, "C"}
3 | {1, "D"} -> {5, "A} -> {6, "F}
In this example you have hashtable with 4-element inner table. This hashtable contains 7 element (7 different keys) but:
key 2 and 3 was placed to the same bucket (they have the same index computed upon hash value) key 1, 5, 6 was placed to the same bucket.
So we can say, there is collision between key=2 and key=3 and between 1,5,6. In other words keys 2 adn 3 are on the same collision list. The same to keys 1,5,6.
You cannot get such collistion list from Hashtable because it is Hashtable internal implementation marked as private:
/**
* Hashtable bucket collision list entry
*/
private static class Entry<K,V> implements Map.Entry<K,V> {
int hash;
final K key;
V value;
Entry<K,V> next;
protected Entry(int hash, K key, V value, Entry<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
...
public V setValue(V value) {
if (value == null)
throw new NullPointerException();
V oldValue = this.value;
this.value = value;
return oldValue;
}
...
public int hashCode() {
return hash ^ value.hashCode();
}
...
}
And Hashtable have its internal bucket table defined as:
/**
* The hash table data.
*/
private transient Entry<K,V>[] table;
Hope this helps to figure out hashtable behavior.
Upvotes: 0
Reputation: 69409
You are currently using i % 10
as your hash map key, which only has ten values (0-9
). Hence only the last ten values are stored in your map, all the others are overriden.
If you need to store more than one item in each bucket, use a list type as your value. For example:
Hashtable<Integer, List<Integer>> ht = new Hashtable<>();
for (int i = 0; i < 100; i++) {
int key = i % 10;
List<Integer> list = ht.get(key);
if (list == null) {
list = new ArrayList<>();
ht.put(key, list);
}
list.add(i);
}
Enumeration<List<Integer>> eles = ht.elements();
while (eles.hasMoreElements()) {
System.out.println(Arrays.toString(eles.nextElement().toArray()));
}
Output:
[9, 19, 29, 39, 49, 59, 69, 79, 89, 99] [8, 18, 28, 38, 48, 58, 68, 78, 88, 98] [7, 17, 27, 37, 47, 57, 67, 77, 87, 97] [6, 16, 26, 36, 46, 56, 66, 76, 86, 96] [5, 15, 25, 35, 45, 55, 65, 75, 85, 95] [4, 14, 24, 34, 44, 54, 64, 74, 84, 94] [3, 13, 23, 33, 43, 53, 63, 73, 83, 93] [2, 12, 22, 32, 42, 52, 62, 72, 82, 92] [1, 11, 21, 31, 41, 51, 61, 71, 81, 91] [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
Upvotes: 6