锁定老帖子 主题:关于Map.entrySet()的疑惑
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-11-09
就是,持久化数据数据的时候出现setter of com.hiber.Hibernate.Test.id 异常. 此异常是提醒,pojo里面未有属性的getter. 因为我在其他方法里面保存过,未曾出现异常,觉得甚是奇怪.后来发现,原来是Map.entrySet()搞的鬼,根据java api. 返回此映射中包含的映射关系的 set 视图。返回的 set 中的每个元素都是一个 Map.Entry。该 set 受映射支持,所以对映射的改变可在此 set 中反映出来,反之亦然。如果修改映射的同时正在对该 set 进行迭代(除了通过迭代器自己的 remove 操作,或者通过在迭代器返回的映射项上执行 setValue 操作外),则迭代结果是不明确的。set 支持通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作实现元素移除,即从映射中移除相应的映射关系。它不支持 add 或 addAll 操作。 为此,我写了一个测试代码. public class TestMap { /** * @param args */ public static void main(String[] args) { Map test = new HashMap(); //测试,put进TestObject for(int i=0; i<5; i++){ TestObject to = new TestObject(); test.put(new Integer(i), to); } //输出,这里进行类型强制转换,出现java.lang.ClassCastException. for(Iterator it = test.entrySet().iterator(); it.hasNext();){ TestObjectt = (TestObject)it.next(); t.toString(); //System.out.println(t.); } //输出,这里直接转换成Object,并且输出的是自己定义的toString() //且可以正常输出,为此,我不理解.为什么转换的时候保存. //估计是里面做了些什么手脚. for(Iterator it = test.entrySet().iterator(); it.hasNext();){ TestObjectt = (TestObject)it.next(); t.toString(); //System.out.println(t.); } } } class TestObject{ public String toString(){ System.out.println("TestObject"); return null; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-11-09
entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现! 包含getKey,getValue等操作!结构类似List! map在rehashing时会重新计算entryset! |
|
返回顶楼 | |
发表时间:2006-11-09
galaxystar 写道 entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现! 包含getKey,getValue等操作!结构类似List! map在rehashing时会重新计算entryset! 但是.我如果直接转换成Object,输出的却是TestObject呢? |
|
返回顶楼 | |
发表时间:2006-11-09
wuhua 写道 galaxystar 写道 entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现! 包含getKey,getValue等操作!结构类似List! map在rehashing时会重新计算entryset! 但是.我如果直接转换成Object,输出的却是TestObject呢? 去看HashMap.Entry的实现啊,必然是调用了Value的toString方法咯... |
|
返回顶楼 | |
发表时间:2006-11-09
Hibernate的 Map重写了java Map呀,所以应该看看Hibernate源码
比较好吧 |
|
返回顶楼 | |
发表时间:2006-11-09
引用 //输出,这里进行类型强制转换,出现java.lang.ClassCastException.
这2段不是一样的吗?而且你前面放test的KEY是Integer啊 ,不知道你们说得这么深奥是干什么哦,还望赐教
for(Iterator it = test.entrySet().iterator(); it.hasNext();){ TestObjectt = (TestObject)it.next(); t.toString(); //System.out.println(t.); } //输出,这里直接转换成Object,并且输出的是自己定义的toString() //且可以正常输出,为此,我不理解.为什么转换的时候保存. //估计是里面做了些什么手脚. for(Iterator it = test.entrySet().iterator(); it.hasNext();){ TestObjectt = (TestObject)it.next(); t.toString(); //System.out.println(t.); } |
|
返回顶楼 | |
发表时间:2006-11-09
galaxystar 写道 entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现! 包含getKey,getValue等操作!结构类似List! map在rehashing时会重新计算entryset! 上面没看清楚,我去查查看。 |
|
返回顶楼 | |
发表时间:2006-11-09
Readonly 写道 wuhua 写道 galaxystar 写道 entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现! 包含getKey,getValue等操作!结构类似List! map在rehashing时会重新计算entryset! 但是.我如果直接转换成Object,输出的却是TestObject呢? 去看HashMap.Entry的实现啊,必然是调用了Value的toString方法咯... 谢谢高手的提示: 我去看了下源代码,已经搞明白了 按照提示:查看代码的流程是 1. //获取EntrySet; public Set entrySet() { Set es = entrySet; return (es != null ? es : (entrySet = new EntrySet())); //HashMap内部实现了个EntrySet } //下面看看EntrySet的实现 private class EntrySet extends AbstractSet { //重点看看这段代码 public Iterator iterator() { return newEntryIterator(); } public boolean contains(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e = (Map.Entry)o; Entry candidate = getEntry(e.getKey()); return candidate != null && candidate.equals(e); } public boolean remove(Object o) { return removeMapping(o) != null; } public int size() { return size; } public void clear() { HashMap.this.clear(); } } 得到Iterator实例:EntryIterator. private class EntryIterator extends HashIterator { public Object next() { return nextEntry(); } } Entry nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); Entry e = next; if (e == null) throw new NoSuchElementException(); Entry n = e.next; Entry[] t = table; int i = index; while (n == null && i > 0) n = t[--i]; index = i; next = n; return current = e; } static class Entry implements Map.Entry { final Object key; Object value; final int hash; Entry next; /** * Create new entry. */ Entry(int h, Object k, Object v, Entry n) { value = v; next = n; key = k; hash = h; } public Object getKey() { return unmaskNull(key); } public Object getValue() { return value; } public Object setValue(Object newValue) { Object oldValue = value; value = newValue; return oldValue; } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e = (Map.Entry)o; Object k1 = getKey(); Object k2 = e.getKey(); if (k1 == k2 || (k1 != null && k1.equals(k2))) { Object v1 = getValue(); Object v2 = e.getValue(); if (v1 == v2 || (v1 != null && v1.equals(v2))) return true; } return false; } public int hashCode() { return (key==NULL_KEY ? 0 : key.hashCode()) ^ (value==null ? 0 : value.hashCode()); } //最后系统调用的是这里的方法. public String toString() { return getKey() + "=" + getValue(); } 哈哈.我明白了. |
|
返回顶楼 | |
发表时间:2006-11-09
我感觉你没真的理解哦,value 的toString()
|
|
返回顶楼 | |
发表时间:2006-11-09
引用 我感觉你没真的理解哦,value 的toString() 愿听您详解 |
|
返回顶楼 | |