java为什么增强的for循环在null上迭代会导致包含16个或更多项的HashMap?

java为什么增强的for循环在null上迭代会导致包含16个或更多项的HashMap?,java,foreach,nullpointerexception,iteration,Java,Foreach,Nullpointerexception,Iteration,我最初使用的代码,对于包含16个或更多元素的任何HashMap,在某些地方返回NullPointerException: for(Entry<Integer, String> e : myHashMap.entrySet()){ System.out.println(e.getKey() + ": "+e.getValue()); } for(条目e:myHashMap.entrySet()){ System.out.println(e.getKey()+“:”+e.get

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

for(Entry<Integer, String> e : myHashMap.entrySet()){
    System.out.println(e.getKey() + ": "+e.getValue());
}
for(条目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
}
inti=0//变量来显示索引
int c=0//变量来计算找到的项目数
而(c
这两者的区别是什么?为什么第一个迭代空值?更重要的是,如果有16个或更多项,为什么第一个项会无序迭代?(即:12,13,17,15,16,19,18,而不是第二节中整洁的12,13,14,15,16,17,18,19)


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

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

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


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

您需要向我们展示如何填充
HashMap
。异常到底是什么样子的?至于排序:
HashMap
是无序的。您不应该期望以任何特定的顺序获取值。我通过提示符手动按顺序填充HashMap,从键开始:值1:“一”,然后是2:“二”,等等。它首先打印空值。我想知道的是这两种迭代方法之间的关键区别是什么?它们不应该有相同的结果吗,或者这是我需要学习java的东西吗?对于集合,迭代的
foreach
方法(您的第一个示例)使用集合中的
iterator()
方法。另外,您应该执行
System.out.println(e.getKey()+“:”+e.getValue())如果要查看每个键映射到的内容。这也可以帮助您确定空值出现的原因。我认为您最好的选择(尤其是因为它只是大小为16或更大的映射)是使用调试器并逐步查找空值的位置。获得NPE的唯一方法是如果e为空,这对我来说没有意义。第一个出现顺序错误的原因是迭代器不能保证在
HashMap
中有任何顺序(至少相对于插入键的方式)。如果希望按输入顺序提取链接,可以使用
LinkedHashMap