java高级HashMap中的entrySet()方法的理解
基础使用:
HashMap集合中的entrySet()方法可以得到各个键值对映射关系的集合。
然后在Map.Entry中包含了getKey()和getValue()方法获取键和值。
示例:
public class Demo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put("abc","123");
map.put("efg", "456");
//使用增强for遍历循环Map集合
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for(Map.Entry<String,String> entry : entrySet){
System.out.println(entry.getKey()+"->"+entry.getValue());
}
}
}
/**
* 打印结果:
* abc-->123
* efg-->456
*/
代码执行原理分析:
HashMap中的entrySet()方法返回Set<Map.Entry<String,String>>,那么为什么entrySet()方法可以得到键值对的映射集合呢?
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}
entrySet方法的方法的原理其实和keySet()方法、values()方法的原理是一样的。
分析entrySet()方法 源码:
/**
* 该方法的返回值就是这个map中各个键值对映射关系集合
* 1.Map中采用是Entry内部类表示一个映射项,映射项包含key和value
* 2.Map.Entry里面包含的getKey()和getValue()方法
* 3.static class Node<K,V> implements Map.Entry<K,V>
*/
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
/**
* 代码等价于(代码复杂化)
* Set<Map.Entry<k,v>> es = entrySet;
* if(es==null){
* entrySet = new EntrySet();
* return entrySet;
* } else {
* return es;
* }
*/
}
我们现在看看编译后的字节码文件Demo.class文件:
public class Demo {
public Demo() {
}
public static void main(String[] args) {
Map<String, String> map = new HashMap();
map.put("abc", "123");
map.put("efg", "456");
Set<Entry<String, String>> entrySet = map.entrySet();
Iterator var3 = entrySet.iterator();
while(var3.hasNext()) {
Entry<String, String> entry = (Entry)var3.next();
PrintStream var1 = System.out;
String var1 = (String)entry.getKey();
var1.println(var1 + "->" + (String)entry.getValue());
}
}
}
/**
* 注意到entrySet调用了iterator()方法、生成的迭代器对象var3 它调用了hasNext()和next()方法
*/
能够获取元素是通过迭代器的遍历得来的,所以entrySet()方法能有键值对的映射集合,是因为有iterator方法。那么我们想一下这个iterator方法是怎么来的呢?是因为entrySet()方法中使用new实例化了一个EntrySet类
我们再查看EntrySet类的源码,里面有个iterator()方法字节码调用的就是这个iterator()方法
在方法的return语句中又实例化了EntryIterator类作为返回值,是一个迭代器,我们现查看EntryIterator类的源码,它只有一个next方法:
final class EntryIterator extends HashIterator
implements Iterator<Map.Entry<K,V>> {
public final Map.Entry<K,V> next() { return nextNode(); }
}
next()方法被调用返回的类型是Map.Entry<K,V>,而得到的结果是nextNode()方法的返回值。
final Node<K,V> nextNode() {
Node<K,V>[] t;
Node<K,V> e = next;
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (e == null)
throw new NoSuchElementException();
if ((next = (current = e).next) == null && (t = table) != null) {
do {} while (index < t.length && (next = t[index++]) == null);
}
return e;
}
nextNode()方法作用就是返回下一个节点。
Node类是HashMap的静态内部类:
Entry是Map的内部接口,该Entry接口有几个方法:
interface Entry<K, V> {
/**...*/
K getKey();
/**...*/
V getValue();
/**...*/
V setValue(V value);
/**...*/
boolean equals(Object o);
/**...*/
int hashCode();
所以我们可以通过entry.getKey() 和 entry.getValue()方法获取到键和值。
注意:Node<K,V>是Map<K,V>的实现类