I have a class called MyClass:
public class MyClass extends abstractClass implements
someInterface {
Set<VNode> relation_;
Set<VNode> x_;
Set<VNode> y_;
@Override
public boolean equals(Object obj) {
if (!super.equals(obj)) {
return false;
}
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof MyClass)) {
return false;
}
MyClass other = (MyClass) obj;
if (relation_ == null) {
if (other.relation_ != null) {
return false;
}
} else if (!relation_.equals(other.relation_)) {
return false;
}
if (x_ == null) {
if (other.x_ != null) {
return false;
}
} else if (!x_.equals(other.x_)) {
return false;
}
if (y_ == null) {
if (other.y_ != null) {
return false;
}
} else if (!y_.equals(other.y_)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int res = new HashCodeBuilder(17, 37).append(relation_).append(x_)
.append(y_).append(getWeight()).toHashCode();
return res;
}
}
The abstract class is as follows:
public abstract class abstractClass {
double weight_;
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof abstractClass)) {
return false;
}
abstractClass other = (abstractClass) obj;
if (Double.doubleToLongBits(weight_) != Double
.doubleToLongBits(other.weight_)) {
return false;
}
return true;
}
public double getWeight() {
return weight_;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(weight_);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
}
Now, if I have HashSet<MyClass> s1
and an MyClass i1
, even if s1
has an element s1i
whith s1i.equals(i1)=true
and s1i.hashCode()=i1.hashCode()
, s1.contains(i1)
gives me false
.
Any explanations?
Other classes:
public class VNode {
Mention mention_;
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof VNode)) {
return false;
}
VNode other = (VNode) obj;
if (mention_ == null) {
if (other.mention_ != null) {
return false;
}
} else if (!mention_.equals(other.mention_)) {
return false;
}
return true;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((mention_ == null) ? 0 : mention_.hashCode());
return result;
}
}
public class Mention extends Range {
private final int id_;
public Mention(final int start, final int end) {
super(start, end);
id_ = getNextMentionID();
}
}
public class Range {
private final int start_;
private final int end_;
/**
* Contr.
*
* @param start
* @param end
*/
public Range(final int start, final int end) {
start_ = start;
end_ = end;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Range)) {
return false;
}
Range other = (Range) obj;
if (end_ != other.end_) {
return false;
}
if (start_ != other.start_) {
return false;
}
return true;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + end_;
result = prime * result + start_;
return result;
}
}
Your equals() method is not readable at all. Since you are using HashCodeBuilder in hashCode(), why not use EqualsBuilder as well?
Version a)
public boolean equals(Object obj){
if(obj == null || obj.getClass()!=getClass()){
return false;
}
MyClass other = (MyClass) obj;
return new EqualsBuilder()
// check parent properties first
.append(this.getWeight(), other.getWeight())
.append(this.relation_, other.relation_)
.append(this.x_, other.x_)
.append(this.y_, other.y_)
.isEquals();
}
Version b)
public boolean equals(Object obj){
// delegate to parent equals first
if(!super.equals(obj)){
return false;
}
MyClass other = (MyClass) obj;
return new EqualsBuilder()
.append(this.relation_, other.relation_)
.append(this.x_, other.x_)
.append(this.y_, other.y_)
.isEquals();
}
Each class should only be concerned with its own variables when calculating equals and hashcode. So, in your MyClass instead of calling getWeight()
you should be using the hashcode of the super class. Like you are with equals()
!. In this case the effect will be the same.
public int hashCode() {
int res = new HashCodeBuilder(super.hashcode(), 37).append(relation_).append(x_)
.append(y_);
return res;
}
This means any changes to the base class that may affect equals and hashcode are confined to the class and you don't have to update the sub classes.
(Not really an answer, more an observation but its too big for a comment)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.