1,介绍
HashTable大部分实现方法和HashMap的实现方法逻辑是一样的,只不过为了线程安全,给方法加了一把锁,没什么可说的,这是只介绍一下遍历HashTable集合元素的几种方法以及源码:
public class HashTableTest {public static void main(String args[]){
Hashtable<String, Integer> table = new Hashtable<String, Integer>();
//[1]添加元素
table.put("zhangsan", 22);
table.put("lisi", 33);
table.put("wangwu", 44);
//[2]toString()方式打印
System.out.println(table.toString());
//[3]Iterator遍历方式1--键值对遍历entrySet()
Iterator<Entry<String, Integer>> iter = table.entrySet().iterator();
while(iter.hasNext()){
Map.Entry<String, Integer> entry = (Map.Entry<String, Integer>)iter.next();
String key = entry.getKey();
int value = entry.getValue();
System.out.println("entrySet:"+key+" "+value);
}
System.out.println("====================================");
//[4]Iterator遍历方式2--key键的遍历
Iterator<String> iterator = table.keySet().iterator();
while(iterator.hasNext()){
String key = (String)iterator.next();
int value = table.get(key);
System.out.println("keySet:"+key+" "+value);
}
//[5]通过Enumeration来遍历Hashtable的key
Enumeration<String> keys = table.keys();
while(keys.hasMoreElements()) {
System.out.println("Enumeration-keys:"+enu.nextElement());
}
//[6]通过Enumeration来遍历Hashtable的value
Enumeration<String> values = table.elements();
while(values.hasMoreElements()) {
System.out.println("Enumeration-values:"+values.nextElement());
}
2,HashTable元素遍历源码分析:
1)通过Enumeration来遍历Hashtable元素源码分析:Enumeration是一种很久的迭代器了,由于Enumeration接口中定义的方法太少,方法名太长(hasMoreElements,nextElement)等原因被淘汰了,jdk1.5虽然进行了功能扩展,但还是被淘汰了,最终被Iterator代替了。
public synchronized Enumeration<K> keys() {
return this.<K>getEnumeration(KEYS);
}
private <T> Enumeration<T> getEnumeration(int type) {
if (count == 0) {
return Collections.emptyEnumeration();
} else {
return new Enumerator<>(type, false);
}
}
Enumerator(int type, boolean iterator) {
this.type = type;
this.iterator = iterator;
}
//从数组的最后一个进行遍历,若取到值,则返回true,若取不到一直循环下去,如果HashTable为空,则返回 false
public boolean hasMoreElements() {
Entry<?,?> 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;
}
//从数组的最后一个进行遍历,当type=KEYS(0)若取到key值返回;当type=VALUES(1)若取到value值返回
public T nextElement() {
Entry<?,?> 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<?,?> e = lastReturned = entry;
entry = e.next;
return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);
}
throw new NoSuchElementException("Hashtable Enumerator");
}
// Iterator methods
public boolean hasNext() {
return hasMoreElements();
}
public T next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
return nextElement();
}
2)通过Iterator迭代器进行遍历
Hashtable<String,String> tab = new Hashtable<String,String>();tab.put("1", "one");
tab.put("2", "two");
Iterator<Entry<String, String>> iter = tab.entrySet().iterator();
while(iter.hasNext()){
Map.Entry<String, String> entry = (Map.Entry<String, String>)iter.next();
String tkey = entry.getKey();
String tvalue = entry.getValue();
System.out.println("entrySet:"+tkey+" "+tvalue);
}
对以上代码的源码进行分析:
public Set<Map.Entry<K,V>> entrySet() {
if (entrySet==null)
//entrySet为null,通过Collections工具类的synchronizedSet初始化一个通过的entrySet
entrySet = Collections.synchronizedSet(new EntrySet(), this);
return entrySet;
}
//SynchronizedSet是Collections类的一个内部类,mutex这个对象就是当前HashTale对象,同步锁需要锁住这个对象
static <T> Set<T> synchronizedSet(Set<T> s, Object mutex) {
return new SynchronizedSet<>(s, mutex);
}
EntrySet类:
private <T> Iterator<T> getIterator(int type) {
if (count == 0) {
return Collections.emptyIterator();
} else {
return new Enumerator<>(type, true);
}
}
Enumerator类中的方法:
private class Enumerator<T> implements Enumeration<T>, Iterator<T> {
Entry<?,?>[] table = Hashtable.this.table;
int index = table.length;
Entry<?,?> entry;
Entry<?,?> lastReturned;
int type;
boolean iterator;
protected int expectedModCount = modCount;
Enumerator(int type, boolean iterator) {
this.type = type;
this.iterator = iterator;
}
public boolean hasMoreElements() {
Entry<?,?> 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;
}
//迭代的逻辑:1,type传的是KEYS的值,迭代式返回的是key的值
2,type传的是VALUES的值,迭代式返回的是value的值
3,type的值是其他,返回entry<key,value>对象
public T nextElement() {
Entry<?,?> 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<?,?> e = lastReturned = entry;
entry = e.next;
return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);
}
throw new NoSuchElementException("Hashtable Enumerator");
}
public boolean hasNext() {
return hasMoreElements();
}
public T next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
return nextElement();
}
}
这里说一下:如果不用迭代器遍历,则直接可以通过HashTable对象调用entrySet成员变量直接遍历
Set<Entry<String, String>> kv = tab.entrySet();