HashMap 是Java開(kāi)發(fā)中經(jīng)常使用的數(shù)據(jù)結(jié)構(gòu)。相信HashMap 的基本用法你已經(jīng)很熟悉了。那么我們?cè)撊绾伪闅vHashMap 呢?哪種遍歷方式的性能更好呢?本篇文章來(lái)為你解決這個(gè)疑惑。
一、HashMap 遍歷
如果你了解一些HashMap 底層原理,那么你肯定知道HashMap 是一個(gè)存儲(chǔ)鍵值對(duì)的集合,每個(gè)鍵值對(duì)叫Entry。Entry 組成的數(shù)組構(gòu)成了整個(gè)HashMap 的主干。Entry 的索引是通過(guò)Hash()方法計(jì)算出來(lái)的。因此Entry在數(shù)組內(nèi)部是無(wú)序的(所以我們不能單純的用for語(yǔ)句有序遍歷)。那么我們?cè)撊绾伪闅vHashMap 呢?
1. 使用EntrySet遍歷
HashMap 的內(nèi)部有一個(gè)EntrySet方法可以讓我們方便地獲取HashMap 數(shù)組內(nèi)的所有Entry。假設(shè)我們有一個(gè)這樣的HashMap。
HashMap<String,Integer> map=new HashMap<String,Integer>();
我們可以這樣獲取EntrySet。
Set<Entry<String, Integer>> entrySet=map.entrySet();
這樣就得到了HashMap 中所有的Entry。獲取Entry 之后遍歷就簡(jiǎn)單多了。我們可以用foreach 語(yǔ)句遍歷
Set<Entry<String, Integer>> entrySet=map.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
或者使用迭代器的方式:
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
System.out.println(entry.getKey()+":"+entry.getValue());
}
2.使用KeySet 遍歷
HashMap 中的KeySet方法可以將把Map中所有的鍵存入到set集合中。再根據(jù)get方法,就可以獲取到每一個(gè)鍵對(duì)應(yīng)的值。 使用KeySet 遍歷的代碼如下:
for (String key : map.keySet()) {
System.out.println(key+":"+map.get(key));
}
補(bǔ)充一點(diǎn),如果你想獲取Hashmap 中所有的value,你可以用values 方法。該方法返回一個(gè)包含所有value 的collection。
Collection<String> collection = map.values();
System.out.println(collection);
二、性能比較
網(wǎng)上對(duì)這兩種遍歷方法進(jìn)行性能比較的文章有很多,我在此就不詳細(xì)比較了。結(jié)論就是,使用EntrySet (也就是第一種方式)進(jìn)行遍歷的性能更好,無(wú)論你是使用foreach還是迭代器,只要你用的是EntrySet 的方式就可以。而KeySet的方式性能就很差,至于KeySet為什么性能很差,我們可以看看遍歷KeySet 時(shí)用到的get() 方法的源碼(JDK 1.6 ver)。
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
可以看出來(lái),源碼先獲取了key 對(duì)應(yīng)的hash值 ,然后根據(jù)hash值在HashMap 的Entry 數(shù)組內(nèi)遍歷出hash值與key的hash值相等的Entry,并返回對(duì)應(yīng)的Value。所以get() 方法在獲取Value 的時(shí)候又進(jìn)行了一次循環(huán),這導(dǎo)致了性能的下降。
三、總結(jié)
總結(jié)一下,我們介紹了兩種遍歷HashMap 的方法,一種是用EntrySet,另一種是用KeySet。性能上EntrySet 優(yōu)于KeySet ,這是因?yàn)镵eySet 的get方法在獲取Value 的時(shí)候需要進(jìn)行遍歷。所以推薦遍歷HashMap 的時(shí)候使用EntrySet 的方法。