谁能给我说明白hashtable中的contains事怎么回事

ddxxtt 2007-03-25 02:25:13
Integer r = new Integer(2);
Integer rr = new Integer(2);
//r和rr不是同一个句柄;这点很明显
Hashtable ht = new Hashtable();
ht.put("1",r);
ht.put("2",rr);
System.out.println(ht.contains(rr));//这里输出为true,请问是怎么回事
ht.clear() ;
ht.put(r,"a");
ht.put("b",rr);
System.out.println(ht.contains(rr));//这里输出也为true,请问是怎么回事
ht.clear() ;
ht.put(r,rr);
System.out.println(ht.contains(rr));//这里输出还是为true,还要请问是怎么回事


contains这个方法到底比较的是什么,是依据什么标准来比较的,比较的是“键”还是“值”??谢谢
...全文
718 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
frilly 2007-03-28
  • 打赏
  • 举报
回复
contains
public boolean contains(Object value)测试此映射表中是否存在与指定值关联的键。此操作比 containsKey 方法的开销更大。
注意,此方法在功能上等同于 containsValue 方法,containValue 是集合框架中 Map 接口的一部分。


参数:
value - 要搜索的值。
返回:
当且仅当此哈希表中某个键映射到 value 参数(由 equals 方法确定)时,返回 true;否则返回 false。
抛出:
NullPointerException - 如果该值为 null。
guichenguang 2007-03-28
  • 打赏
  • 举报
回复
Integer r = new Integer(2);
Integer rr = new Integer(2);

问题应该是出在这里的!! r and rr 引用的都是 Integer(2);
改为
Integer r = new Integer(2);
Integer rr = new Integer(3); 就哦了.
qzjackie 2007-03-27
  • 打赏
  • 举报
回复
boolean contains(Object value)
测试此映射表中是否存在与指定值关联的键。
---------------------------------
你是不是要说。当键的时候是true
当值的时候为什么也是true
????
-----------------------------------------------------
回复人:Dan1980() ( 五级(中级)) 信誉:98 2007-3-25 14:54:12 得分:0
?

好像没人答到点子上啊。

contains()比较的是值,这点是肯定的。关键问题在于这个“等于”关系的标准是什么,也就是说,contains的参数和Hashtable中的值这两个对象符合什么样的条件才认为是相等的,从而让contains返回true。

这个等于关系是在equals()中定义的。

众所周之,Integer类重写了Object中的equals()方法,让它不再比较句柄,而是比较对象中实际包含的整数的值。这就是为什么楼主的程序返回true的原因。因为equals()被contains()方法回调了,contains利用equals()的返回值。

如果楼主自己写一个类,如:

// T.java
public class T {
int value;
public T(int val) {
value = val;
}
}

再把你程序中的Integer用T来替换,那得到结果应当是false。

这是因为T类没有重写equals()方法,而是直接继承了Object的equals(),这使得比较标准仍然是比较对象的句柄。

一般来说,如果你要把一个类的对象放入容器中,那么通常要为其重写equals()方法。
特别地,如果要把你的类的对象放入散列中,那么还要重写hashCode()方法;要放到有序容器中,还要重写compareTo()方法。
==============================
这个朋友说得不错哦。
你是只安下面的改一下。就不会行了。
int r = 2;
int rr = 2;

iamsangster 2007-03-27
  • 打赏
  • 举报
回复
sorry


hashtable 的value 不能为Null
iamsangster 2007-03-27
  • 打赏
  • 举报
回复
这儿有NullPointerException
--------------------------------------------------------

if (e.value.equals(value)) {
return true;
}
iamsangster 2007-03-27
  • 打赏
  • 举报
回复
public synchronized boolean contains(Object value) {
if (value == null) {
throw new NullPointerException();
}

Entry tab[] = table;
for (int i = tab.length ; i-- > 0 ;) {
for (Entry e = tab[i] ; e != null ; e = e.next) {
if (e.value.equals(value)) {
return true;
}
}
}
return false;
}
interpb 2007-03-25
  • 打赏
  • 举报
回复
呵呵

楼上的态度很诚恳哦

syhan 2007-03-25
  • 打赏
  • 举报
回复
我错了,我想当然了:(
查了下api
contains

public boolean contains(Object value)

测试此映射表中是否存在与指定值关联的键。此操作比 containsKey 方法的开销更大。

注意,此方法在功能上等同于 containsValue 方法,containValue 是集合框架中 Map 接口的一部分。

参数:
value - 要搜索的值。
返回:
当且仅当此哈希表中某个键映射到 value 参数(由 equals 方法确定)时,返回 true;否则返回 false。

interpb 2007-03-25
  • 打赏
  • 举报
回复
syhan(藏书人)

你确定是搜索Key和value一起搜索吗
interpb 2007-03-25
  • 打赏
  • 举报
回复
首先要确定, contains 方法只搜索value 不搜索 key


我看不懂你的的三个输出有什么区别
三个都是搜索rr 而且三个map 都有value rr 你的疑问在哪里

你的意思是不是 后面两个 ht.contains(rr) 你写错了 你的本意是ht.contains(r)

是这样吗

我刚刚看了源代码 HashMap的contains方法是通过equals方法来判断 是不是有对象存在的
而显然

System.out.println(r.equals(rr)); 这个是true的

既然r 与 rr在map看来就是一个对象,而且Map里面有rr 你调用ht.contains(r)肯定返回true了
syhan 2007-03-25
  • 打赏
  • 举报
回复
使用contains既搜索Key,也包括Value,ht.contains(rr));也就是说查询当前的Hashtable里key或value里是否包含rr这个对象,很显然,你那三个都含有
shengli_liao 2007-03-25
  • 打赏
  • 举报
回复
xuexi...
sonic_andy 2007-03-25
  • 打赏
  • 举报
回复
http://doc.javacn.com/java/util/Hashtable.html
laitaogood 2007-03-25
  • 打赏
  • 举报
回复
直接看DOC 不就可以了嘛
kai8145802 2007-03-25
  • 打赏
  • 举报
回复
key的哈希码
Dan1980 2007-03-25
  • 打赏
  • 举报
回复
好像没人答到点子上啊。

contains()比较的是值,这点是肯定的。关键问题在于这个“等于”关系的标准是什么,也就是说,contains的参数和Hashtable中的值这两个对象符合什么样的条件才认为是相等的,从而让contains返回true。

这个等于关系是在equals()中定义的。

众所周之,Integer类重写了Object中的equals()方法,让它不再比较句柄,而是比较对象中实际包含的整数的值。这就是为什么楼主的程序返回true的原因。因为equals()被contains()方法回调了,contains利用equals()的返回值。

如果楼主自己写一个类,如:

// T.java
public class T {
int value;
public T(int val) {
value = val;
}
}

再把你程序中的Integer用T来替换,那得到结果应当是false。

这是因为T类没有重写equals()方法,而是直接继承了Object的equals(),这使得比较标准仍然是比较对象的句柄。

一般来说,如果你要把一个类的对象放入容器中,那么通常要为其重写equals()方法。
特别地,如果要把你的类的对象放入散列中,那么还要重写hashCode()方法;要放到有序容器中,还要重写compareTo()方法。
luffywang 2007-03-25
  • 打赏
  • 举报
回复
不错,不太清楚的地方多看看文档

62,614

社区成员

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

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