Overriding hashcode and equals method in java?
Solution 1
are you looking something like following? Just try it, as from your question i think you want to compare contents of your Sample class also.
class Sample implements java.io.Serializable{
//POJO with two fields and getters/setters
private String name;
private Integer id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
//This POJO does not override equals() and hashCode()
}
public class Beta implements Comparable{
private Sample sample;
public Sample getSample() {
return sample;
}
public void setSample(Sample sample) {
this.sample = sample;
}
@Override
public int compareTo(Object o) {
if(!(o instanceof Beta)){
return -1;
}
}if(((Beta)o).getSample().getName().equals(this.sample.getName())){
return 0; // return true if names are equal
}
if(((Beta)o).getSample().getId().equals(this.sample.getId())){
//if name are notequal and IDs are equal, do what you need to do
}
return -1;
}
public static void main(String[] args) {
Beta b = new Beta();
Sample s = new Sample();
s.setId(10);
s.setName("Name1");
b.setSample(s);
Beta b2 = new Beta();
Sample s2 = new Sample();
s2.setId(20);
s2.setName("Name2");
b2.setSample(s2);
System.out.println(b2.compareTo(b));
Beta b3 = new Beta();
Sample s3 = new Sample();
s3.setId(10);
s3.setName("Name1");
b3.setSample(s3);
System.out.println(b3.compareTo(b));
}
}
Overriding approach
class Sample implements java.io.Serializable{
//POJO with two fields and getters/setters
private String name;
private Integer id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
//This POJO does not override equals() and hashCode()
}
public class Beta /*implements Comparable*/{
private Sample sample;
public Sample getSample() {
return sample;
}
public void setSample(Sample sample) {
this.sample = sample;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Beta other = (Beta) obj;
if ((this.getSample() == null) && (other.getSample() == null)){
return true;
}
if ((this.getSample().getId().equals(other.getSample().getId())) && (this.getSample().getName().equals(other.getSample().getName()))) {
return true;
}
return false;
}
@Override
public int hashCode() {
int hash = 3;
hash = 53 * hash + (this.getSample().getName() != null ? this.getSample().getName().hashCode() : 0);
hash = 53 * hash + (this.getSample().getId() != null ? this.getSample().getId().hashCode() : 0);
return hash;
}
/* @Override
public int compareTo(Object o) {
if(!(o instanceof Beta)){
return -1;
}
if(((Beta)o).getSample().getId().equals(this.sample.getId()) && ((Beta)o).getSample().getName().equals(this.sample.getName())){
return 0;
}
return -1;
}*/
public static void main(String[] args) {
Beta b = new Beta();
Sample s = new Sample();
s.setId(10);
s.setName("Name1");
b.setSample(s);
Beta b2 = new Beta();
Sample s2 = new Sample();
s2.setId(20);
s2.setName("Name2");
b2.setSample(s2);
System.out.println(b2.equals(b));
Beta b3 = new Beta();
Sample s3 = new Sample();
s3.setId(10);
s3.setName("Name1");
b3.setSample(s3);
System.out.println(b3.equals(b));
}
Solution 2
If you don't explicitly override .equals()
, they will be compared based solely off of their references (despite not having a equals()
, every object inherits one from Object
). If you only want B
to be compared based off of Sample
, then simply do the following:
@Override
public boolean equals(Object o)
{
if (o istanceof B)
{
return sample.equals(o.sample)
}
return false;
}
Additionally, you should then override hashCode()
(and compareTo()
) to maintain the contract between equals()
and hashCode()
. Hence, you should also have the following:
@Override
public int hashCode()
{
return sample.hashCode();
}
EDIT (in response to comment):
My requirement is first i need to check equals property against "name" property of Sample. IF names are equals then both objects are equal. If names are not equals then i need to check for equality against "ID" property of Sample. How can i do that? Thanks!
Determining whether Samples
are equivalent should be handled in Sample
, by overriding equals()
. If equals()
for Sample
bases off of name
and id
, then you're fine. If you want to compare Samples
in B
differently than they are normally compared, then you're not going to be able to maintain the contract between equals()
and hashCode()
for B
if you use hashCode()
or equals()
from Sample
, which means that your hashCode()
and equals()
for B
should be cannot call equals()
or hashCode()
from Sample
. See this tutorial for how to override based on specific fields.
user755806
Updated on June 16, 2022Comments
-
user755806 almost 2 years
I have the classes below:
public class Sample implements java.io.Serializable{ //POJO with two fields and getters/setters private String name; private Integer id; //This POJO does not override equals() and hashCode() } public class B{ private Sample sample; //here i need override hashcode and equals() based on **sample** property. }
When i tried overriding equals() and hashCode() in the B class I got the error below in Eclipse.
The field type com.mypackage.Sample does not implement hashCode() and equals() - The resulting code may not work correctly.
Now how can I compare two B instances whether equals or not based on the Sample property? I cannot modify Sample class.
-
user755806 over 10 yearsI tried. But still i get "The field type com.mypackage.Sample does not implement hashCode() and equals() - The resulting code may not work correctly". any suggestions?
-
Steve P. over 10 years@user755806 This definitely works, I believe that your IDE is simply telling you that you're not explicitly overriding
hashCode()
andequals()
. Make sure that you have also overriddenhashCode()
forB
--I made an edit stating how to do this. If this is not done, then you will not be maintaining the contract ofequals()
andhashCode()
. If your IDE still yells at you, it's just a warning to make sure that you understand that forSample
you're using the default methods instead of overriding. -
user755806 over 10 yearsSteve, thanx for your reply. My requirement is first i need to check equals property against "name" property of Sample. IF names are equals then both objects are equal. If names are not equals then i need to check for equality against "ID" property of Sample. How can i do that? Thanks!
-
Steve P. over 10 years@user755806 You're asking multiple questions here...This should be handled in
Sample
. As in overridingequals()
fromSample
. If this is not the way thatSamples
should normally be compared, or you are unable to do that, then you're not going to be able to maintain theequals()
andhashCode()
contract, which means that you cannot do what you want to do. See this tutorial for how to override based on specific fields. -
user755806 over 10 yearsVD, yes exactly this is what i was looking for.My requirement is first i need to check equals property against "name" property of Sample. IF names are equals then both objects are equal. If names are not equals then i need to check for equality against "ID" property of Sample. How can i do that? Thanks!
-
dev2d over 10 yearsi have edited the code for your requirement, you can refer overriding approach from stackoverflow.com/questions/8180430/…
-
dev2d over 10 yearsi have also edited the code for overriding hashcode and equals methods