关于证明HashMap是按散列码排序的问题的问题...

本文通过一个具体实例探讨了Java中HashMap的存储及打印顺序,并通过自定义散列码验证了HashMap并非按散列码排序。
thinking in java中第11章课后第9题:
原题:使用键值对填充HashMap.打印结果,证明是按散列码排序的.
代码:如下
主程序:
public class _09_HashMapAndLinkedHashMapTest {
public static void main(String[] args) {
HashMap m = new HashMap();
for(int i = 0;i<10;i++)
m.put(new Groundhog2(i), new Object());
System.out.println("Printing Map: \n" + m);//直接打印:
Set s = m.keySet();//取出键值
System.out.println("Key Set: \n" + s);//打印键值
Iterator it = s.iterator();
while (it.hasNext()) {
Object o = it.next();
System.out.println("Key=" + o + ", hashcode="//打印键值和键值的散列码
+ o.hashCode());
}
}
}
Groundhog2代码:
public class Groundhog2 extends Groundhog{
public Groundhog2(int n){
super(n);
}
//散列函数用于计算散列码
public int hashCode(){
System.out.println("Groundhog2.hashcode()");
return number;
}
public boolean equals(Object o){
System.out.println("Groundhog2.equals()");
return (o instanceof Groundhog2) && (number == ((Groundhog2)o).number);
}
}

打印效果:
Printing Map:
{Groundhog #2=java.lang.Object@d9f9c3,
Groundhog #4=java.lang.Object@9cab16,
Groundhog #9=java.lang.Object@1a46e30,
Groundhog #8=java.lang.Object@3e25a5,
Groundhog #6=java.lang.Object@19821f,
Groundhog #1=java.lang.Object@addbf1,
Groundhog #3=java.lang.Object@42e816,
Groundhog #7=java.lang.Object@9304b1,
Groundhog #5=java.lang.Object@190d11,
Groundhog #0=java.lang.Object@a90653}
Key Set:
[Groundhog #2, Groundhog #4, Groundhog #9, Groundhog #8, Groundhog #6, Groundhog #1, Groundhog #3, Groundhog #7, Groundhog #5, Groundhog #0]

Key=Groundhog #2, hashcode=2
Key=Groundhog #4, hashcode=4
Key=Groundhog #9, hashcode=9
Key=Groundhog #8, hashcode=8
Key=Groundhog #6, hashcode=6
Key=Groundhog #1, hashcode=1
Key=Groundhog #3, hashcode=3
Key=Groundhog #7, hashcode=7
Key=Groundhog #5, hashcode=5
Key=Groundhog #0, hashcode=0
问题:乍看之下:不是按散列码排序的呀?为什么呢?请指点一下?
Java 中,`HashMap` 的 `entrySet()` 方法用于返回一个包含 `HashMap` 中所有键值对(`Map.Entry` 对象)的 `Set` 视图。这些 `Map.Entry` 对象包含了键和对应的值,可通过它方便地遍历 `HashMap` 中的所有元素。 ### 使用方法 以下是 `entrySet()` 方法的使用示例: ```java import java.util.HashMap; import java.util.Map; public class MapExample { public static void main(String[] args) { // 创建一个 HashMap 并添加元素 Map<String, Integer> map = new HashMap<>(); map.put("Apple", 1); map.put("Banana", 2); map.put("Cherry", 3); // 使用 entrySet() 方法遍历 HashMap for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } } } ``` 上述代中,通过 `map.entrySet()` 获取 `HashMap` 中所有键值对的 `Set` 视图,然后使用 `for-each` 循环遍历该 `Set`。在每次循环中,使用 `entry.getKey()` 获取键,使用 `entry.getValue()` 获取对应的值,并将它们打印输出 [^1]。 ### 作用 - **遍历 `HashMap`**:`entrySet()` 方法提供了一种方便的方式来遍历 `HashMap` 中的所有键值对。通过遍历 `entrySet()` 返回的 `Set`,可以直接访问每个键值对的键和值,而不需要先获取键的集合,再根据键去获取对应的值。 - **同步修改 `HashMap`**:在遍历过程中,如果需要修改 `HashMap` 的内容(如删除元素),使用 `entrySet()` 结合 `Iterator` 可以安全地进行操作,避免 `ConcurrentModificationException` 异常。 ### 性能特点 - **空间开销**:`entrySet()` 方法返回的 `Set` 视图是一个轻量级的对象,它并不存储实际的键值对,而是引用了 `HashMap` 中的键值对,因此不会额外占用大量的内存空间。 - **时间复杂度**:遍历 `entrySet()` 返回的 `Set` 的时间复杂度为 O(n),其中 n 是 `HashMap` 中键值对的数量。 ### 注意事项 - **线程安全问题**:如果在多线程环境下使用 `HashMap`,并且需要遍历 `entrySet()`,需要注意线程安全问题。`HashMap` 是非线程安全的,如果在遍历过程中其他线程修改了 `HashMap` 的结构,可能会导致 `ConcurrentModificationException` 异常。可以考虑使用线程安全的 `ConcurrentHashMap` 来避免此类问题 [^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值