`
wuhua
  • 浏览: 2099389 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

关于Map.entrySet()的疑惑

阅读更多
前几天项目用到Map,接着调用Map.entrySet(),结果产生了一些意外的后果.
就是,持久化数据数据的时候出现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;
	}
}

分享到:
评论
11 楼 我不知道 2007-06-26  
这段代码的输出隐蔽性很强啊。呵呵
追究根源才是真理。
10 楼 jianfeng008cn 2006-11-11  
Readonly 写道
wuhua 写道
galaxystar 写道
entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现!
包含getKey,getValue等操作!结构类似List!
map在rehashing时会重新计算entryset!


但是.我如果直接转换成Object,输出的却是TestObject呢?

去看HashMap.Entry的实现啊,必然是调用了Value的toString方法咯...

上面人家已经说了呀,
你放进去的是TestObject 为什么转成Object后就该是Object 的 toString() 呀,输出是TestObject的 不是很正常?你看了map的源代码就说知道了,可这里面的关系和这个错误关系不大吧,我感觉你的理解就好象把一个对象转成接口来调用的时候方法都变空了。
9 楼 wuhua 2006-11-09  
引用
我感觉你没真的理解哦,value 的toString()

愿听您详解
8 楼 jianfeng008cn 2006-11-09  
我感觉你没真的理解哦,value 的toString()
7 楼 wuhua 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();
        }




哈哈.我明白了.
6 楼 jianfeng008cn 2006-11-09  
galaxystar 写道
entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现!
包含getKey,getValue等操作!结构类似List!
map在rehashing时会重新计算entryset!

上面没看清楚,我去查查看。
5 楼 jianfeng008cn 2006-11-09  
引用
//输出,这里进行类型强制转换,出现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.);  
        }  
这2段不是一样的吗?而且你前面放test的KEY是Integer啊 ,不知道你们说得这么深奥是干什么哦,还望赐教
4 楼 ASDF1982 2006-11-09  
Hibernate的 Map重写了java Map呀,所以应该看看Hibernate源码
比较好吧
3 楼 Readonly 2006-11-09  
wuhua 写道
galaxystar 写道
entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现!
包含getKey,getValue等操作!结构类似List!
map在rehashing时会重新计算entryset!


但是.我如果直接转换成Object,输出的却是TestObject呢?

去看HashMap.Entry的实现啊,必然是调用了Value的toString方法咯...
2 楼 wuhua 2006-11-09  
galaxystar 写道
entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现!
包含getKey,getValue等操作!结构类似List!
map在rehashing时会重新计算entryset!


但是.我如果直接转换成Object,输出的却是TestObject呢?
1 楼 galaxystar 2006-11-09  
entrySet迭代出来的是Map.Entry对象,当然会出现ClassCastException!
Entry对象里是map结构的一种内部实现!
包含getKey,getValue等操作!结构类似List!
map在rehashing时会重新计算entryset!

相关推荐

    java循环Map java迭代Map

    Map a = new HashMap(); //方法一 Iterator it = a.entrySet().iterator(); while (it.hasNext()) { ...for(Map.Entry entry:a.entrySet()){ System.out.println(entry.getKey()+"="+entry.getValue()); }

    java中Map集合的常用遍历方法及HashMap的应用实例

    1、遍历Map.entrySet():它的每一个元素都是Map.Entry对象,这个对象中, 放着的就是Map中的某一对key-value; 2、遍历Map.keySet():它是Map中key值的集合,我们可以通过遍历这个集合来 读取Map中的元素; 3、...

    android控件监听管理工具

    for(Map.Entry,Object&gt; entry:data.entrySet()){ View v = (View) entry.getKey(); v.setOnClickListener(null); } } private void registerLisntener(){ for(Map.Entry,Object&gt; entry:data.entrySet...

    自定义MyHashMap集合及entrySet()实现.md

    用自定义的MyHashMap彻底了解EntrySet ()方法,及put()和get()方法实现

    怎样遍历一个HashMap?

    &lt;br&gt;for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { &lt;br&gt; Map.Entry entry = (Map.Entry) iter.next(); &lt;br&gt; Object key = entry.getKey(); &lt;br&gt; Object val = entry.getValue()...

    java遍历特例

    Iterator it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); Object key = entry.getKey(); Object value = entry.getValue(); } Map map =...

    JSON依赖包,共7个

    Iterator it=map.entrySet().iterator(); while(it.hasNext()){ Map.Entry m = (Map.Entry) it.next(); String key=(String)m.getKey(); String value=(String) m.getValue(); System.out....

    JAVA遍历Map所有元素.doc

    java.util.Map.Entry entry = (java.util.Map.Entry) it.next(); System.out.print(entry.getValue()); } System.out.println(); System.out.println(Calendar.getInstance().getTimeInMillis() - bs); } } ``...

    java Map 遍历方法

    java Map 遍历方法 Map map = new HashMap(); Iterator it = map.entrySet().iterator(); while (it.hasNext()) {

    重要知识java中map集合的用法.pdf

    遍历 Map 集合有多种方式,例如使用 `keySet()` 方法获取所有键,使用 `entrySet()` 方法获取所有键值对,使用 `values()` 方法获取所有值。例如: ``` for (Object o : map.keySet()) { map.get(o); } ``` 或 ``` ...

    java桑硅谷 day23 晨考.zip

    import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; public class TestTreeMap { public static void main(String[] args) { TreeMap, ArrayList&lt;City&gt;&gt; map = new TreeMap(); ...

    pageDate封装参数,不用实体类

    return map.entrySet(); } public boolean isEmpty() { // TODO Auto-generated method stub return map.isEmpty(); } public Set keySet() { // TODO Auto-generated method stub return map.keySet(); ...

    全量断言方法-Java版

    for (Map.Entry, Object&gt; m : exp.entrySet()) { //如果value是JSONObject类型,则将该类型转化成Map类型,继续循环比较 if (JSONObject.class == m.getValue().getClass()) { Map, Object&gt; expDataInfo = ...

    JavaScript中实现Map的示例代码

    map.entrySet() // 返回Entity[{key,value},{key,value}] map.containsKey('kevin') //返回:false function Map() { this.keys = new Array(); this.data = new Object(); /** * 放入一个键值对 * @par

    java遍历Map对象的说有数据

    &lt;FONT color=#0000ff&gt;//方法一: 用entrySet() Iterator it = emails.entrySet().iterator();... Map.Entry m=(Map.Entry)it.next(); logger.info("email-" + m.getKey() + ":" + m.getValue()); }

    金陵科技学院软件院大二上Java高级1212Map.docx

    1212Map.doc 目的: 学会使用 Map、TreeMap 完成内容 1. 定义 Map, 加入一些数据 使用 entrySet 方式显示全部键、值其内容 使用 keySet 方式显示全部键、值内容 使用 values 显示全部值内容

    模拟实现购物车功能

    import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * 购物车类 */ public class Cart { //创建一个map对象,用来保存商品,key为商品,value为商品的数量 private Map, Integer&gt; ...

    模拟购物车

    import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * 购物车类 */ public class Cart { //创建一个map对象,用来保存商品,key为商品,value为商品的数量 private Map, Integer&gt; ...

    怎么在java 8的map中使用stream

    文章目录简介基本概念使用Stream获取map的key使用stream获取map的value总结 怎么在java 8的map中使用stream 简介 Map是java中非常常用的一个集合类型,我们通常也需要去...Set&lt;Map&gt; entries = someMap.entrySet(); 获

    android 视频播放器demo

    for(Map.Entry, String&gt; entry: params.entrySet()){ pathBuilder.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue())).append("&"); } //...

Global site tag (gtag.js) - Google Analytics