java源码分析之HashMap(六)

2014-11-24 11:24:54 · 作者: · 浏览: 43
这里为什么不直接操作table而是通过tab呢?希望有知道的大侠指点一二。
主要方法看的差不多了,接着看一个上面提到了好几次但是都搁在一边没有分析的方法:entrySet()。
entrySet()
1 public Set> entrySet() {
2 return entrySet0();
3 }
4
5 private Set> entrySet0() {
6 Set> es = entrySet;
7 return es != null es : (entrySet = new EntrySet());
8 }
为什么会有这样的方法,只是调用了一下entrySet0,而且entrySet0的名称看着就很奇怪。再看entrySet0方法中为什么不直接return entrySet!=null entrySet:(entrySet = new EntrySet)呢?
上面的疑问还没解开,但是先看entrySet这个属性吧,在文章开头的属性定义中并没有给出这个属性,下面先看一下它的定义:
1 private transient Set> entrySet = null;
它是一个内容为Map.Entry的Set。看看在哪些地方往里面添加了元素。
为什么上面的那句话我要把它标成红色?因为这是一个陷阱,在看代码的时候我就陷进去了。
仔细看EntrySet这个类。
1 private final class EntrySet extends AbstractSet> {
2 public Iterator> iterator() {
3 return newEntryIterator();
4 }
5 public boolean contains(Object o) {
6 if (!(o instanceof Map.Entry))
7 return false;
8 Map.Entry e = (Map.Entry) o;
9 Entry candidate = getEntry(e.getKey());
10 return candidate != null && candidate.equals(e);
11 }
12 public boolean remove(Object o) {
13 return removeMapping(o) != null;
14 }
15 public int size() {
16 return size;
17 }
18 public void clear() {
19 HashMap.this.clear();
20 }
21 }
看到了什么?这个类根本就没属性,它只是个代理。因为它内部类,可以访问外部类的内容,debug的时候能看到的属性都是继承或者外部类的属性,输出的时候其实也是调用到了父类的toString方法将HashMap中的内容输出了。
keySet()
1 public Set keySet() {
2 Set ks = keySet;
3 return (ks != null ks : (keySet = new KeySet()));
4 }
是不是和entrySet0()方法很像!
1 private final class KeySet extends AbstractSet {
2 public Iterator iterator() {
3 return newKeyIterator();
4 }
5 public int size() {
6 return size;
7 }
8 public boolean contains(Object o) {
9 return containsKey(o);
10 }
11 public boolean remove(Object o) {
12 return HashMap.this.removeEntryForKey(o) != null;
13 }
14 public void clear() {
15 HashMap.this.clear();
16 }
17 }
同样是个代理类,contains、remove、clear方法都是调用的HashMap的方法。
values()
1 public Collection values() {
2 Collection vs = values;
3 return (vs != null vs : (values = new Values()));
4 }
5
6 private final class Values extends AbstractCollection {
7 public Iterator iterator() {
8 return newValueIterator();
9 }
10 public int size() {
11 return size;
12 }
13 public boolean contains(Object o) {
14 return containsValue(o);
15 }
16 public void clear() {
17 HashMap.this.clear();
18 }
19 }
values()方法也一样是代理。只是Values类继承自AbstractCollention类,而不是AbstractSet。
还有一个重要的内容没有进行说明,那就是迭代器。HashMap中的entrySet()、keySet()、values()等方法都使用到了迭代器Iterator的知识。其他集合类也有使用到迭代器