Reputation: 1128
The problem:
I want to have a Map in java like this:
Map<Double,List<MyClass>> map = new HashMap<Double,List<MyClass>>();
I want to basically group MyClass objects based on a double value.
But Key (Double) is experimental data and it has noise in it. I wish to add items to the same list even if the key is a little bit different.
For eg:
If I have key = 1300.5
inside the map already, if the new value that I am trying to add is newKey = 1300.7
say,
when I say map.containsKey(newKey)
I want the map to return true
Also when I say map.get(newKey)
I want it to return the corresponding list value of key=1300.5
to which I will then add a new MyClass
.
What have I done so far:
I created this class which would now be my key instead of Double
class NearestFreq{
Double freq;
@Override
public boolean equals(Object obj) {
System.out.println("inside equals method...");
if(Math.abs(this.freq-((NearestFreq)obj).freq)<Constants.range){
return true;
}
else {
return false;
}
}
public NearestFreq(Double freq) {
super();
this.freq = freq;
}
}
I expected that this would then make the map assume two keys are the same if they are within the error bars. I changed my map to:
Map<NearestFreq,List<MyClass>> map = new HashMap<NearestFreq,List<MyClass>();
But I found that the map's containsKey() call did not call NearestFreq's .equals()
method ( "inside equals method..."
never got printed ), which I did not understand why.
Can anyone tell me how do I accomplish this?
Upvotes: 1
Views: 47
Reputation: 1128
I found a workaround.
What I did was to change HashMap<>
to TreeMap<>
Implement Comparable
interface for NearestFreq
and
override the compareTo Method to:
@Override
public int compareTo(NearestFreq o) {
if(Math.abs(this.freq-((NearestFreq)o).freq)<range){
return 0;
}
else if((this.freq-((NearestFreq)o).freq) <0) {
return -1;
}
else if((this.freq-((NearestFreq)o).freq) >0) {
return 1;
}
return 0;
}
and it works!
Upvotes: 1
Reputation: 9953
You're using a HashMap so map inserts call the hashCode
method to figure out where in the map the item should go. equals
is called only if there's a collision.
As a general rule in Java, if you override equals
or hashCode
you should always override the other as well to ensure that a.hashCode() == b.hashCode()
if a.equals(b)
is true.
Upvotes: 2