Vivek V K
Vivek V K

Reputation: 1128

Map with an error bar on key in java?

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

Answers (2)

Vivek V K
Vivek V K

Reputation: 1128

I found a workaround.

  1. What I did was to change HashMap<> to TreeMap<>

  2. Implement Comparable interface for NearestFreq and

  3. 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

Oliver Dain
Oliver Dain

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

Related Questions