HashMap中keySet()底层调用解析
来源:互联网 发布:java调dll内存泄露 编辑:程序博客网 时间:2024/06/07 06:55
问题:HashMap的keySet()方法底层如何调用的?
首先看keySet()的使用:
Map<String, Integer> map = new HashMap<String, Integer>(); map.put("a", 1); map.put("b", 2); map.put("c", 3); Set<String> ks = map.keySet(); for (String s: ks){ System.out.println(s); }
再看HashMap中keySet()方法:
public Set<K> keySet() { Set<K> ks = keySet; return (ks != null ? ks : (keySet = new KeySet())); }
而且keySet成员初始为null,且并没有在构造函数中初始化过
transient volatile Set<K> keySet = null;
所以初次调用keySet()方法时会new KeySet(),而KeySet()是一个内部类
private final class KeySet extends AbstractSet<K> { public Iterator<K> iterator() { return newKeyIterator(); } public int size() { return size; } public boolean contains(Object o) { return containsKey(o); } public boolean remove(Object o) { return HashMap.this.removeEntryForKey(o) != null; } public void clear() { HashMap.this.clear(); } }
这个时候我们只是新建了一个KeySet 内部类对象,并没有调用其他方法,而且内部类KeySet 的父类无参构造函数也并没有做啥,那么问题来了,我们是怎么获取的HashMap中的key值的,之前对这个问题一直没明白。
其实,Set ks = map.keySet(); 这里的 ks 就仅仅只是一个Set引用,指向HashMap内部类KeySet的一个实例,重点在于该实例拥有自己的迭代器,当我们在使用增强for循环时才会调用该迭代器,也才会输出我们想要的东西。
现在看看迭代器是如何工作的:
private final class KeySet extends AbstractSet<K> { public Iterator<K> iterator() { return newKeyIterator(); }}
newKeyIterator()是指向外部类的一个函数
Iterator<K> newKeyIterator() { return new KeyIterator();}
现在又指向创建的另一个内部类对象KeyIterator(),该类继承HashIterator也是HashMap的内部类
private final class KeyIterator extends HashIterator<K> { public K next() { return nextEntry().getKey(); } }
当我们在增强for循环时会调用该next()方法,它指向的是nextEntry().getKey(),Entry中不仅存放了key,value,也存放了next,指向下一个Entry对象,我们知道,HashMap的数据层实现是数组+链表,nextEntry会先遍历链表,然后再继续遍历下一个数组位置的链表,直至全部遍历完成,其部分源码如下:
if ((next = e.next) == null) { Entry[] t = table; while (index < t.length && (next = t[index++]) == null) ;}
总结:keySet()方法返回一个内部引用,并指向一个内部类对象,该内部类重写了迭代器方法,当在增强for循环时才调用,并从外部类的table中取值。
- HashMap中keySet()底层调用解析
- HashMap底层之entrySet,keySet,value实现
- Java中HashMap底层实现
- HashMap中keySet()以及values()方法的使用
- HashMap中keySet()以及values()方法的使用
- 实在没想到系列——HashMap实现底层细节之keySet,values,entrySet的一个底层实现细节
- Hashmap 中的Keyset()方法
- HashMap中的keySet
- HashMap的entrySet与keySet
- HashMap的entrySet与keySet
- HashMap中的keySet()和entrySet()
- JAVA中HashMap基本底层原理
- 浅析Java中HashMap的底层原理
- HashMap底层
- Java中HashMap两种遍历方法(keyset & entryset快)
- Java7和Java8的HashMap底层思想解析
- keySet 与entrySet 遍历HashMap性能差别
- HashMap的keyset与value的对应
- 高斯消元
- 总结PLSQL的快捷键以及使用技巧
- Java过滤器及其特性
- 给你一段英文或德文文字,统计文字中字母“t”(或“T”)与“s”(或“S”)出现的次数, 如果给定文字中“t”(或“T”)的出现次数比“s”多,则可能为英文,否则可能为德文
- hdu 1078
- HashMap中keySet()底层调用解析
- PHP基础数据类型之整型
- 两个输入框水平排列
- Python-Numpy(2)Array数组操作
- 初学manacher
- 文章标题
- Eclipse .java文件 颜色+几何形状的意义
- SVM入门(六)线性分类器的求解——问题的转化,直观角度
- curl请求https POST和GET方法