hashtable,底层是个table,hashtable吧table的index给hash了一下。
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V old = e.value;
e.value = value;
return old;
}
}
modCount++;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
Entry<K,V> e = tab[index];
tab[index] = new Entry<K,V>(hash, key, value, e);
count++;
return null;
}
存完了之后,里面的table可能是这样的(在我这里这次运行)
[null, null, null, null, 0=Hamster:0, 1=Hamster:1, 2=Hamster:2, 3=Hamster:3, null, null, null]
-------------------------------------------------------
在这段代码里
04. static void print(Enumeration e){
05. while (e.hasMoreElements())
06. {
07. System.out.println(
08. e.nextElement().toString()
09. );
10. }
11. }
-----迭代用到的两个方法hasMoreElements()和nextElement()的代码如下:
public boolean hasMoreElements() {
Entry<K,V> e = entry;
int i = index;
Entry[] t = table;
/* Use locals for faster loop iteration */
while (e == null && i > 0) {
e = t[--i];
}
entry = e;
index = i;
return e != null;
}
-----
public T nextElement() {
Entry<K,V> et = entry;
int i = index;
Entry[] t = table;
/* Use locals for faster loop iteration */
while (et == null && i > 0) {
et = t[--i];
}
entry = et;
index = i;
if (et != null) {
Entry<K,V> e = lastReturned = entry;
entry = e.next;
return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);
}
throw new NoSuchElementException("Hashtable Enumerator");
}
从这两个方法的实现里就应该能看到原因了,简单说就是,存的时候是随机存的,取的时候是倒着取的。
----
在我这里存的是按顺序存的,我感觉这可能是种偶然吧,毕竟hash应该是无序的。所以,取出来的是倒序也就是一种偶然,在更多的情况下,取出来的应该是无序的。 |