我在这两个类下面有..
class Emp //implements Comparable
{
String name,job;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
int salary;
public Emp(String n,String j,int sal)
{
name=n;
job=j;
salary=sal;
}
public void display()
{
System.out.println(name+"t"+job+"t"+salary);
}
public boolean equals(Object o)
{
Emp p=(Emp)o;
return this.name.equals(p.name)&&this.job.equals(p.job) &&this.salary==p.salary;
}
/* public int hashCode()
{
return name.hashCode()+job.hashCode()+salary;
}
*/
/* public int compareTo(Object o)
{
Emp e=(Emp)o;
return this.name.compareTo(e.name);
//return this.job.compareTo(e.job);
// return this.salary-e.salary;
}*/
}
另一个是..
import java.util.*;
class EmpHsDemo
{
public static void main(String arg[])
{
HashSet set=new HashSet();
set.add(new Emp("Ram","Trainer",34000));
set.add(new Emp("Ram","Trainer",34000));
set.add(new Emp("Ravi","Administrator",44000));
set.add(new Emp("Sachin","Programmer",24000));
set.add(new Emp("Priyanka","Manager",54000));
set.add(new Emp("Anupam","Programmer",34000));
set.add(new Emp("Sachin","Team Leader",54000));
System.out.println("There are "+set.size()+" elements in the set.");
System.out.println("Content of set are : ");
Iterator itr=set.iterator();
while(itr.hasNext())
{
Emp e=(Emp)itr.next();
System.out.print(e.hashCode()+"t");
e.display();
}
System.out.println("**********************************");
Emp e1=new Emp("Ravi","Administrator",44000);
System.out.println("Removing following Emp from the set...");
System.out.print(e1.hashCode()+"t");
e1.display();
set.remove(e1);
System.out.println("No. of elements after removal "+set.size());
/* Emp e2=new Emp("Anupam","Programmer",34000);
System.out.println("Searching following Emp in the set...");
System.out.print(e2.hashCode()+"t");
e2.display();
System.out.println("Results of searching is : "+set.contains(e2));*/
}
}
现在我正在做一项研究,即
如果我评论hashcode()方法
- 而不是评论等于()方法,它将使用它允许重复,因为Ram显示两次以及内存地址,我得到以下结果。
There are 7 elements in the set.
Content of set are :
374283533 Priyanka Manager 54000
1660364311 Ram Trainer 34000
1340465859 Ravi Administrator 44000
2106235183 Sachin Programmer 24000
2031692173 Ram Trainer 34000
603737068 Anupam Programmer 34000
148669801 Sachin Team Leader 54000
**********************************
Removing following Emp from the set...
1807500377 Ravi Administrator 44000
No. of elements after removal 7
阿拉伯数字。如果我取消注释哈希码()方法和等于()方法,我会得到这个结果
There are 6 elements in the set.
Content of set are :
1546622676 Sachin Team Leader 54000
-302767206 Anupam Programmer 34000
149315535 Ravi Administrator 44000
199998062 Sachin Programmer 24000
1407883922 Priyanka Manager 54000
597555555 Ram Trainer 34000
**********************************
Removing following Emp from the set...
149315535 Ravi Administrator 44000
No. of elements after removal 5
3 .如果我只评论等于()方法而不是哈希码(),那么我会得到以下结果
There are 7 elements in the set.
Content of set are :
1546622676 Sachin Team Leader 54000
-302767206 Anupam Programmer 34000
149315535 Ravi Administrator 44000
199998062 Sachin Programmer 24000
1407883922 Priyanka Manager 54000
597555555 Ram Trainer 34000
597555555 Ram Trainer 34000
**********************************
Removing following Emp from the set...
149315535 Ravi Administrator 44000
No. of elements after removal 7
请告知那里的三种方法背后的资源..!
不值得阅读您发布的所有信息。
Joshua Bloch说hashCode和equals应该一起被覆盖。 这是你应该怎么做,没有例外。
HashSet 有许多存储桶。它使用hashCode()
来确定元素属于哪个存储桶,然后在该存储桶中,它使用equals()
来查找该元素是否存在于该存储桶中。
这些方法的默认实现hashCode()
使用系统标识哈希码,这可能是它的内存位置,但它的独特之处在于系统将尝试使用所有"合理实用"的尝试,使没有两个对象具有相同的系统标识哈希码,并且等于比较两个对象的内存位置。(请注意,系统标识哈希码不能保证产生唯一的哈希;相反,它非常、非常、非常努力地尝试为您提供唯一的哈希。有关此问题的进一步阅读,请参阅 Java Bug 6321873。
因此,有了这些知识,就可以通过各种方法的逻辑应用来预测不同的方法,无论它们是实现的还是使用默认实现的。
在第一种情况下,Ram 显示在两个不同的存储桶中,因此两个 Ram 对象永远不会相互比较。使用以下行比较它们(至少在 Sun 实现中)
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
这是遍历存储桶中的每个对象。它们的哈希值不相等,因此它永远不会检查确定对象本身是否等于所提供的哈希值。
在您的第二种情况下,它的工作方式如您所料,请注意,具有两个不同职位和薪水的人将被视为不同的人。
在第三种情况下,Ram 两次进入同一个桶。但是,由于使用了默认的 equals 方法,并且这两个对象是不同的对象,因此会再次添加它。
同样值得重申的是,duffymo的回答完全忽略了你的问题;在99.9%的情况下,我会说这是错误的做法,我们应该首先了解你的问题范围。这是极少数忽略您的问题是正确的情况之一。您永远不应该只覆盖哈希代码和等于之一。你应该总是不做或两者都做,永远不要只做一个。
1.当2个对象相等时,它们应该有same hashcode
。
2. 如果 2 个对象有 same hascode,
那么它们必须相互调用 equals() 以查看它们是否相等。
3.如果哈希码匹配,则它们不一定相等。
4.因此,当equals()
方法被覆盖时,也必须覆盖hashcode()
方法,这一点非常重要。
5. HashSet
在检查该对象在HashSet
中的位置时,是否有任何具有相同哈希码的对象,如果有,则两者都被放入一个以same hashcode
为标签的存储桶中,然后互相调用equals()
以查看它们是否真的相等。
HashSet
使用HashMap
作为数据的内部表示。 HashSet.add()
和HashSet.remove()
处理hash
值(您在hashCode()
方法中提供的值。一旦你评论hashCode()
,所有的赌注都关闭了。
在这一点上,我的心有点与duffymo有关,但另一方面,我几乎同样恶毒地反对做某事,因为你的权威告诉你,没有理解。
corsiKa回答正确。只是再加几点来简化事情。@user1582269您使用的设置算法和哈希是使用了数据结构。根据 Set 概念 - Set 中的每个元素都应该是唯一的。不允许元素重复。在哪个基础上元素是唯一的?为了实现这种唯一性,应该覆盖等于()方法。 即 Emp 1 应与 Emp 2 不同。现在您正在使用 哈希数据结构 。哈希可确保元素的存储、检索和搜索方式。为了使哈希有效地工作,哈希函数即哈希代码()应该被覆盖,这样就不会有任何冲突。
应该阅读corsiKa的解释以获取有关哈希的更多解释。因此,如果您不覆盖 hashCode(),默认的 hashCode() 实现将返回一些存储桶 ID(假设数组中的某个索引)例如 4。因此,如果 empX 元素已经存储在存储桶 id 4 处,并且对于另一个员工 empY 返回相同的哈希代码,即 4,那么 empX 和 empY 之间将发生冲突。
希望这能澄清您的疑问。