【问题标题】:Java Map<Integer, HashMap<String, String>>Java Map<Integer, HashMap<String, String>>
【发布时间】:2012-05-26 09:53:11
【问题描述】:

我需要将结果集转换为地图地图。 我不使用地图列表的原因是我不想遍历整个列表来获取特定行。

我现在面临的问题是,如果索引大于 16,则 HashMap 的条目不再排序。

现在我尝试了以下简单测试:

    public static void main(String[] args) {

    Map<Integer, String> map = new HashMap<Integer, String>();

    //creating 20 rows from 1 to 20
    for (int i = 1; i <= 20; i++){
        map.put(i, "ROW "+i);   
    }


    //returning all the rows the map contains. Look at position 16.
    for(int key : map.keySet()){
        System.out.println(key);    
    }
}

输出如下(看位置 16 到 20。它们完全无序):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 16 19 18 20

如果有人能解释为什么会发生这种情况,我将不胜感激。

顺便说一句:

我不能使用这样的东西:

for (int i = 0; i < map.size; i++){
    map.get(i) //...and so on

}

因为我不知道索引是否存在。可能是从200到800的索引不存在。所以最好只遍历地图的现有条目。

【问题讨论】:

    标签: java list collections map hashmap


    【解决方案1】:

    HashMap 未排序或排序。如果您需要插入订购Map使用java.util.LinkedHashMap。 如果您需要按键排序的Map,请使用SortedMap,例如java.util.TreeMap

    【讨论】:

      【解决方案2】:

      您可以使用LinkedHashMap 来保持插入顺序,因为基本映射不保证键的顺序。

      【讨论】:

        【解决方案3】:

        您应该使用 TreeMapLinkedHashMap 而不是 HashMap,具体取决于您是否希望元素分别按其自然顺序或插入顺序排序。

        HashMap 不保证键的顺序。我引用的其他两个 Map 实现确实如此。

        TreeMap 将根据键的自然顺序对键进行排序,这意味着键必须实现 Comparable 或者您必须提供自己的比较器才能确定顺序。

        LinkedHashMap 将根据插入时间保持键的顺序。

        由于您正在寻找的行为是让键自然排序,并且您碰巧自己按顺序插入键,因此任何一种实现都适用于这种情况。

        【讨论】:

          【解决方案4】:

          使用 TreeMap 怎么样?而不是HashMap。您甚至可以提供自己的订单。

          【讨论】:

          • TreeMap 比较浪费资源,听起来OP不需要自定义排序,只需要保持插入顺序即可。
          【解决方案5】:

          我不使用地图列表的原因是我不想遍历整个列表来获取特定行。

          所以将其设为ArrayList 而不是LinkedList。这样,list.get(1234) 将直接进入该条目——它不会遍历之前的 1234 个条目。

          【讨论】:

            【解决方案6】:

            我认为您面临的问题是因为 HashMap 的默认大小。

            根据标准 java 文档,

            /**
             * The default initial capacity - MUST be a power of two.
             */
            static final int DEFAULT_INITIAL_CAPACITY = 16;
            /**
             * The load factor used when none specified in constructor.
             */
            static final float DEFAULT_LOAD_FACTOR = 0.75f;
            
            /**
             * Constructs an empty <tt>HashMap</tt> with the default initial capacity
             * (16) and the default load factor (0.75).
             */
            public HashMap() {
                this.loadFactor = DEFAULT_LOAD_FACTOR;
                threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
                table = new Entry[DEFAULT_INITIAL_CAPACITY];
                init();
            }
            

            所以,在第 16 个元素之后,您没有得到正确的输出。

            根据JavaDoc,

            /**
             * Constructs an empty <tt>HashMap</tt> with the specified initial
             * capacity and the default load factor (0.75).
             *
             * @param  initialCapacity the initial capacity.
             * @throws IllegalArgumentException if the initial capacity is negative.
             */
            public HashMap(int initialCapacity) {
                this(initialCapacity, DEFAULT_LOAD_FACTOR);
            }
            

            尝试以下(具有初始容量的参数化构造函数),

            Map<Integer, String> map = new HashMap<Integer, String>(32);
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-04-07
              • 2019-12-06
              • 1970-01-01
              • 1970-01-01
              • 2016-06-11
              • 1970-01-01
              • 2015-07-08
              相关资源
              最近更新 更多