明明在hashMap存入三项,怎么size只有一项?

孤尽JavaSea 2010-09-02 10:31:32
import java.util.HashMap;
import java.util.Map;

public class MapEQ {
public static void main(String[] args) {
Map<ToDos, String> m = new HashMap<ToDos, String>();
ToDos t1 = new ToDos("Monday");
ToDos t2 = new ToDos("Monday");
ToDos t3 = new ToDos("Tuesday");
m.put(t1, "doLaundry");
m.put(t2, "payBills");
m.put(t3, "cleanAttic");
System.out.println(m.size()); //我觉得应该是3才对。
}
}
class ToDos{
String day;
ToDos(String d){
day = d;
}
public boolean equals(Object o){
return ((ToDos)o).day == this.day;
}
public int hashCode(){
return 9;
}
}
...全文
204 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
hardycheng 2010-09-02
  • 打赏
  • 举报
回复
你的代码
m.put(t1, "doLaundry");
m.put(t2, "payBills");
m.put(t3, "cleanAttic");

你换成

m.put("doLaundry, "t1);
m.put("payBills", t2);
m.put("cleanAttic", t3);

这样就是3了
龙思霓 2010-09-02
  • 打赏
  • 举报
回复
if (e.hash == hash && key.equals(e.key)) {
preModify(e);
V oldValue = e.value;
e.value = value;
return oldValue;
}


大家看好这段了 要两个条件同事满足 才会当成是一个新的 对象放进去 !
龙思霓 2010-09-02
  • 打赏
  • 举报
回复
LZ的编译器 真厉害! 最后跑出来了一个 size=1 。jdk生气了 嘻嘻!
把 equals hashCode 任何一个方法去掉 都是 size=3
sky123123 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用楼主 java_gannbare 的回复:]
Java code
import java.util.HashMap;
import java.util.Map;

public int hashCode(){
return 9;
}
[/Quote]

是这段代码惹的祸。。。
不能飞的肥燕 2010-09-02
  • 打赏
  • 举报
回复
HashTable, HashMap, HashSet等是根据hashcode来判断是否相同的。
TreeSet等式根据equals()来判断的。
ameyume 2010-09-02
  • 打赏
  • 举报
回复
结果为2,
如果去掉
public int hashCode(){
return 9;
}

结果就是3了。

那就是说t1,t2完全相等,导致t2覆盖了t1.
guanchaoti 2010-09-02
  • 打赏
  • 举报
回复
hashMap存的时候如果KEY相同会覆盖前面的 比较KEY是否相同就是根据对象的EQUEALS方法 你前两个对象都是MONDAY hashMap中第2个覆盖了第1个 结果应该是2 改了其中一个monday结果就是3了
xuxianyue 2010-09-02
  • 打赏
  • 举报
回复
结果应该为2,比较两个对象是否一样是通过equals方法和hashcode方法两个方法的
返回值比较,完全一样则对象为同一个。
jinancf 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 tassdars 的回复:]
楼主把hashCode()方法的值写死了,所有对象的hashCode都一样,HashMap之所以叫"Hash",肯定是靠hashCode存取对象的,楼主好好理解一下hashCode再说,建议看看Thinking in java上关于hashCode的论述,hashCode()方法不能乱覆盖的。
[/Quote]
同意
zhuzeitou 2010-09-02
  • 打赏
  • 举报
回复
    @Override public V put(K key, V value) {
if (key == null) {
return putValueForNullKey(value);
}

int hash = secondaryHash(key.hashCode());
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
preModify(e);
V oldValue = e.value;
e.value = value;
return oldValue;
}
}

// No entry for (non-null) key is present; create one
modCount++;
if (size++ > threshold) {
tab = doubleCapacity();
index = hash & (tab.length - 1);
}
addNewEntry(key, value, hash, index);
return null;
}


源码……
人家要比较key和hash这两样东西的
michaellufhl 2010-09-02
  • 打赏
  • 举报
回复
如果用new ToDos(new String("xxx"));就是size=3了。
这一定不是您程序的意图,所以用equals代替==比较String。
yaoweijq 2010-09-02
  • 打赏
  • 举报
回复
楼主的程序我跑了下
结果是2
不清楚楼主的1是怎么跑出来的

public boolean equals(Object o){
return ((ToDos)o).day == this.day;
}
public int hashCode(){
return 9;
}

在一个类可能会放入hashmap等用hash的数据结构的时候
一定要保证equals和hashcode返回相等
楼主这样写有问题,可能会引起程序的不正常结果
建议修改为string 的hashcode
另外由于string都放在字符串常量池的缘故,
这个equals方法中的==竟然在这个小程序里面正常工作了
还是改为string 的equals比较合理一些
孤尽JavaSea 2010-09-02
  • 打赏
  • 举报
回复
那返回的也是1,按照你们的意思。。。。
Tassdars 2010-09-02
  • 打赏
  • 举报
回复
楼主把hashCode()方法的值写死了,所有对象的hashCode都一样,HashMap之所以叫"Hash",肯定是靠hashCode存取对象的,楼主好好理解一下hashCode再说,建议看看Thinking in java上关于hashCode的论述,hashCode()方法不能乱覆盖的。
sunjinyujeep 2010-09-02
  • 打赏
  • 举报
回复
看错了,你的map应该是2个值啊,因为前两个对象是一样的,t2把t1给覆盖了,所以你的map的size应该为2
sunjinyujeep 2010-09-02
  • 打赏
  • 举报
回复
后面的把前面的覆盖了,因为这3个的key都是ToDos对象,由于map的key唯一性所以map里面只有一个值
zhuzeitou 2010-09-02
  • 打赏
  • 举报
回复
hashcode都一样,自然就在put时被直接覆盖了……

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧