我用了IdentityHashMap这个类,把相同的键值放进去,问题就来了,当我读取的时候这个map的时候,每次的顺序都不同,有什么办法可以让它来原来放进去的顺序原样输出?Map map = new java.util.IdentityHashMap();
map.put("a",1);
map.put("b",2);
map.put("c",3);
map.put("a",4);上面代码是每次读出来的顺序都有可能不一样.

解决方案 »

  1.   

    Map map = new java.util.IdentityHashMap();
    改为
    Map map = new java.util.LinkedHashMap();
      

  2.   


    不能用LinkedHashMap,用LinkedHashMap就不能有相同的key了
      

  3.   

    java.util.IdentityHashMap结构存储是随机的,遍历也必然是随机的说,你想按顺序的话,就得重新封装一个处理类。
      

  4.   

    public class IdentityHashMapOperate
    {
        public static IdentityHashMap addValue(IdentityHashMap map, String key, Object value)
        {
            if(map.get("sort").toString() == null)//没有顺序控制key
            {
                map.put("sort", key);//直接增加顺序控制key
                map.put(key, value);
            }
            else
            {
                  String sort = map.get("sort").toString();//取出顺序控制key
                  sort+= "^"+key;//需要控制顺序的key
                  map.put("sort", sort);//回写到map
                  map.put(key, value);
            }        return map;
        }    public static ArrayList getValues(IdentityHashMap map)
        {
            String sort = map.get("sort").toString();
            ArrayList values = new ArrayList();        if(sort != null)
            { 
                String[] sortKeys = sort.split("\\^");            for(int i = 0; i < sortKeys.length; i++)
                {
                    values.add(map.get(sortKeys[i]));
                }
            }
            return values;
        }
    }大概如此了。
      

  5.   

    使用的时候:
    Map map = new java.util.IdentityHashMap();
    map = IdentityHashMapOperate.addValue(map, "a", 1);//用这个类的方法来维护map
    想获得顺序的值:
    ArrayList list = IdentityHashMapOperate.getValues(map);
    当然,还需要完成其他配套的方法,比如删除key之类的就不给你写了,思路就是如此,交给一个新的类去维护它,相当于给它增添了新的规则。
      

  6.   

    Map map = new java.util.IdentityHashMap();
    map.put("a",1);
    map.put("b",2);
    map.put("c",3);
    map.put("a",4);试了下,你这个结果其实也是不重复的。
      

  7.   

    经过测试的新类:
    package cn.com.medicon.test;import java.util.ArrayList;
    import java.util.IdentityHashMap;public class IdentityHashMapOperate
    {
        public static IdentityHashMap addValue(IdentityHashMap map, String key, Object value)
        {
            if(map.get("sort") == null)//没有顺序控制key
            {
                map.put("sort", key);//直接增加顺序控制key
                map.put(key, value);
            }
            else
            {
                  String sort = map.get("sort").toString();//取出顺序控制key
                  sort+= "^"+key;//需要控制顺序的key
                  map.put("sort", sort);//回写到map
                  map.put(key, value);
            }        return map;
        }    public static ArrayList getValues(IdentityHashMap map)
        {
            String sort = map.get("sort").toString();
            ArrayList values = new ArrayList();        if(sort != null)
            { 
                String[] sortKeys = sort.split("\\^");            for(int i = 0; i < sortKeys.length; i++)
                {
                    String key = sortKeys[i];
                    Object value = map.get(key.intern());
                    values.add(value);
                }
            }
            return values;
        }
    }包名别忘了改哈,这是我自己的测试包。测试类:
    public class FilterTest
    {
        public static void main(String[] args)
        {
            IdentityHashMap map = new IdentityHashMap();
            map = IdentityHashMapOperate.addValue(map, "a", 1);
            map = IdentityHashMapOperate.addValue(map, "b", 2);
            map = IdentityHashMapOperate.addValue(map, "c", 3);
            map = IdentityHashMapOperate.addValue(map, "d", 4);
            ArrayList list = IdentityHashMapOperate.getValues(map);
            for(int i = 0; i<list.size();i++)
            {
                System.out.println(list.get(i));
            }
        }
    }
      

  8.   


    treelist ? java ?
      

  9.   

    IdentityHashMap本身就不保证顺序的,况且仅相同的key无法区分顺序,是不是要将整个Entry作为比较对象了
      

  10.   

    IdentityHashMap 与其它 MAP 最大的区别在于它不调用 Object.hashCode() 方法而是使用 System.identityHashcode(),所以,当你的 key 的 hashcode 方法也返回 System.identityHashcode 的值的话,那你就可以不必使用 IdentityHashMap 而使用 LinkedHashMap 就解决问题了嘛,当然前提是你的 key, 你不能再用你举的例子中那样使用 String 类当 key 而是必须 Wrap 成另一个使用前面说到的 hashcode() 的类。
      

  11.   

    首先针对这种问题,你描述的还不够仔细,你还应该说说这个map应用的场景,有什么要求,是否必须透明地使得map.values()或者map.entrySet()维持一个顺序,另外这个顺序是否必须是插入顺序,如果不是插入顺序,但保证每次迭代顺序都相同又是否可行。
    1、如果,这个设计的要求,如你所说的需要严格保证:必须插入顺序,map是交给另外程序通过values()来迭代的,那么你只能重写自己的HashMap,参考LinkedHashMap的代码和IdentityHashMap结合一下,很容易就整出一个,另外LinkedHashMap还额外提供了访问顺序,这部分你可以剔除;
    2、你是否能够接受一个并非插入顺序的固定顺序迭代,同时使用a==b替代a.equals(b)的哈希表呢?比如按照内存地址的排序顺序,如果可以,那么我可以提供一个比较简洁的实现方案:public static void main(String...args) throws Exception{
        String a="1";
        String b="2";
        String c="3";
        a+=b+c;
        b="1"+b+c;
        c="1"+"2"+"3";
        System.out.println(a+","+b+","+c+","+(a==b)+","+(b==c));
        Map map=new TreeMap(new Comparator<Object>(){
          @Override
          public int compare(Object a,Object b){
            return System.identityHashCode(a)-System.identityHashCode(b);
          }
        });
        map.put(c,"3");
        map.put(b,"2");
        map.put(a,"1");
        System.out.println(map.get(a));
        System.out.println(map.get(b));
        System.out.println(map.get(c));
        new IdentityHashMap();
      }觉得这个题目比较有意思,一时兴起随便写的,就算能用你也多测试测试哦!!!
      

  12.   

    补充下,程序应该是这个:public static void main(String...args) throws Exception{
        String a="1";
        String b="2";
        String c="3";
        a+=b+c;
        b="1"+b+c;
        c="1"+"2"+"3";
        System.out.println(a+","+b+","+c+","+(a==b)+","+(b==c));
        Map map=new TreeMap(new Comparator<Object>(){
          @Override
          public int compare(Object a,Object b){
            return System.identityHashCode(a)-System.identityHashCode(b);
          }
        });
        map.put(c,"3");
        map.put(b,"2");
        map.put(a,"1");
        Iterator it=map.values().iterator();
        while(it.hasNext()){
          System.out.println(it.next());
        }
      }多跑几次,会发现每次的顺序不一致,这与每次运行期的内存地址分配有关,但是在同一次执行时,无论如何对map进行修改,都会严格按照内存地址排序,而且符合IdentityHashMap的特性!
      

  13.   


    我是后来改过你的那个报错的是可以运行,而且如果最后用ArrayList输出来的时候确实是没问题,问题现在最后又要放回map里面,根据IdentityHashMap 的特性,最后的顺序还是乱了
      

  14.   


    我觉得你说的有道理,只能重写HashMap,用LinkedHashMap的代码和IdentityHashMap结合就刚好符合我想要的结果,不知道能否提供一下,我不知道怎么改呢
      

  15.   

    LinkedHashMap和它的名字一样,意思就是用一个链接表来维持其顺序,简单来说就是
    Entry header总是第一项
    第一次增加时,替换header为新元素,
    第二每次增加,架设为newEntry,那么header.after=newEntry
    而后的每次增加,都在链表尾部.after=newEntry。
    为了能够快速定位链表尾部,你可以把header.before=newEntry,形成一个双向环状的链表其实最麻烦的是HashMap和IdentityHashMap中有一些方法是包访问级别的,合并起来估计不能继承HashMap,要复制所有代码,生改!