0

我最初使用的代码在某些地方为包含 16 个或更多元素的任何 HashMap 返回了 NullPointerException:

for(Entry<Integer, String> e : myHashMap.entrySet()){
    System.out.println(e.getKey() + ": "+e.getValue());
}

我现在使用的代码适用于同一个 HashMap,无论大小如何:

int i = 0; //variable to show the index
int c = 0; //variable to count the number items found
while(c < myHashMap.size()){
    if(myHashMap.containsKey(i)){ //if the HashMap contains the key i
        System.out.println(i + ": "+myHashMap.get(i)); //Print found item
        c++; //increment up to count the number of objects found
    }
    i++; //increment to iterate to the next key
}

两者有什么区别?为什么第一个迭代空值?而且,更重要的是,如果有 16 个或更多项目,为什么第一个会乱序迭代?(即:12,13,17,15,16,19,18 而不是第二个中整齐的 12,13,14,15,16,17,18,19)

我想我才刚刚开始接触 java 的表面,所以我想了解为什么它是这样设计的。欢迎任何关于这类事情的书籍推荐。

4

1 回答 1

2

在开始使用它之前,您应该阅读一个类的文档并尝试了解它的用途。HashMap提供有效的存储但没有保证的顺序。巧合的是,您没有发现它具有较小HashMap的大小,因为默认容量是并且连续对象16的哈希码也是连续的。Integer但这不是您可以依赖的财产。你总是必须假设没有保证的订单HashMap

如果需要插入顺序,可以使用 a LinkedHashMap,如果需要键的升序,可以使用 a TreeMap。如果你有一个连续的Integer键范围并且想要升序,你也可以简单地使用一个数组。

foreach 循环for(Entry<Integer, String> e : myHashMap.entrySet())不会“遍历空值”。它遍历包含HashMap其中的值,这些值是您之前添加的值。null如果您添加了它,则映射中最多可以包含一个键。在查看未使用插槽的 a 的内部数组时,您可能会在调试器中看到值,因为a的null容量可能于其大小HashMapHashMap

于 2013-10-23T20:46:09.740 回答