【问题标题】:When using a HashMap are values and keys guaranteed to be in the same order when iterating?使用 HashMap 时,值和键在迭代时是否保证顺序相同?
【发布时间】:2010-09-12 18:47:29
【问题描述】:

当我迭代值或键时,它们会相互关联吗?第二个键会映射到第二个值吗?

【问题讨论】:

    标签: java collections hashmap


    【解决方案1】:

    不,不一定。为此,您应该真正使用 entrySet().iterator()。使用此迭代器,您将遍历 Map 中的所有 Map.Entry 对象,并且可以访问每个键和关联的值。

    【讨论】:

      【解决方案2】:

      使用@Cuchullain 提到的entrySet:

      Map<String, String> map = new HashMap<String, String>();
      
      // populate hashmap
      
      for (Map.Entry<String, String> entry : map.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
        // your code here
      }
      

      【讨论】:

        【解决方案3】:

        你想用这个 LinkedHashMap 来预测迭代顺序

        【讨论】:

        • ...或者 LinkedHashSet 如果你需要一个确定性的有序集合
        【解决方案4】:
        public class Test {
         public static void main(String[] args) {
          HashMap <String,String> hashmap = new HashMap<String,String>();
          hashmap.put("one", "1");
          hashmap.put("two", "2");
          hashmap.put("three", "3");
          hashmap.put("four", "4");
          hashmap.put("five", "5");
          hashmap.put("six", "6");
        
          Iterator <String> keyIterator   = hashmap.keySet().iterator();
          Iterator <String> valueIterator = hashmap.values().iterator();
        
          while(keyIterator.hasNext()) {
           System.out.println("key: "+keyIterator.next());
          }
        
          while(valueIterator.hasNext()) {
           System.out.println("value: "+valueIterator.next());
          }
         }
        }
        
        key: two
        key: five
        key: one
        key: three
        key: four
        key: six
        value: 2
        value: 5
        value: 1
        value: 3
        value: 4
        value: 6
        

        【讨论】:

          【解决方案5】:

          values() 和 keySet() 都委托给 entrySet() 迭代器,因此它们将以相同的顺序返回。但就像 Alex 所说,直接使用 entrySet() 迭代器要好得多。

          【讨论】:

          • 这是一个实现细节。我认为不能保证这是真的。
          【解决方案6】:

          我同意 pmac72。不要假设您会从无序集合中获得有序值或键。如果它不时起作用,那只是纯粹的危险。如果您想保留订单,请使用 LinkedHashMap 或 TreeMap 或公共集合 OrderedMap。

          【讨论】:

            【解决方案7】:

            这个问题一开始让我很困惑,但@Matt 为我解决了这个问题。

            考虑使用 entrySet() 方法,该方法返回一个集合,其中包含 Map 上的键值对。

            Map<Integer, Integer> a = new HashMap<Integer, Integer>(2);
            a.put(1, 2);
            a.put(2, 3);
            for (Map.Entry<Integer, Integer> entry : a.entrySet()) {
                System.out.println(entry.getKey() + " => " + entry.getValue());
            }
            

            这个输出:

            1 => 2
            2 => 3
            3 => 3
            

            【讨论】:

            • 我认为这也是问题的最初含义,但听起来他正在使用 .keys() 和 .values() 方法独立地迭代键和值。我不认为 LinkedHashMap 在这种情况下解决了问题
            • 另一方面,您永远不应该创建与预期元素数量相同大小的 HashMap。 HashMap 的负载因子通常为 75%。这意味着,如果地图已满 75%,并且您添加了一个元素,它将增加它的大小。
            【解决方案8】:

            我第二个@basszero。而

            for (Map.Entry<Integer, Integer> entry : a.entrySet()) 
            

            会起作用,我发现使用自动执行此操作的数据结构更好。现在,您可以“正常”迭代

            【讨论】:

              【解决方案9】:

              HashMap的keySet方法返回一个Set,不保证顺序。
              HashMap 的 values() 方法返回一个 Collection,它不保证顺序。

              也就是说,问题是“它们是否会相关”,所以从技术上讲答案是可能的,但不要依赖它。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2016-07-14
                • 2012-09-30
                • 2021-10-21
                • 1970-01-01
                • 1970-01-01
                • 2019-03-17
                • 2010-12-25
                相关资源
                最近更新 更多