LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Custom java Map keys (https://www.linuxquestions.org/questions/programming-9/custom-java-map-keys-553892/)

enemorales 05-14-2007 06:15 PM

Custom java Map keys
 
Hi there,

I'm trying to use a map in Java where the keys are a class of my own:

Code:

public class IntPair {
        private final int x;
        private final int y;
               
        public IntPair(final int x, final int y) {
                this.x = x;
                this.y = y;
        }
               
        public IntPair() {
                x = y = 0;
        }
               
        public int getx() { return x; }
               
        public int gety() { return y; }

        public String toString() {
                return String.format("(%d,%d)",x,y);
        }
                               
} // class IntPair

Here is an example of use:

Code:

               
Map<IntPair,Integer> h = new HashMap<IntPair,Integer>();

IntPair r1 = new IntPair(10,2);
h.put(r1, 5);
h.put(new IntPair(10,2), 8);
h.put(new IntPair(10,2), 543);

for (IntPair r : h.keySet()) {
        System.out.println(r + ":" + h.get(r));
}

So, you see, I've used three times the IntPair(10,2), hence after executing this I would like the Map to have only one element, which key the IntPair(10,2) and with value 543, but I instead of that I get three different instances, each one pointing to one different value: 5, 8 and 543.

I've tried overriding the equals method and also the hashCode() method in IntPair(), but I have had no success: I still get three elements in the Map instead of one.

Is there a way to solve this? How?

I think java is using the references/addresses for the objects to calculate the actual keys that it uses internally in the Map. The problem is that I wouldn't want to keep the references to the keys in the Map. I would like, for instance, to add new values using h.put(new IntPair(x,y)) and then being able, in another place in the program, whether new IntPair(x,y) is a key in the Map...

Thank you a lot in advance.

Seagull 05-15-2007 04:43 AM

What happens if you use :

Code:

h.put(r1, 5);
h.put(r1, 8);
h.put(r1, 543);

Thereby using the same object as the key.

Guttorm 05-15-2007 06:31 AM

Hi

I'm not very good in Java, but I guess you need to make an "equals" method in the IntPair class. I think the default "equals" method is the same as "==" so there will only be a match when the references are the same. How else can the HashMap know if two object are "equal"? And I think if you make an equals method, you should make an hashCode method as well. Two equal objects should make the same hashCode, I don't know if they will do that using the default hashCode.

theYinYeti 05-15-2007 07:45 AM

Absolutely. You must override equals and hashcode as explained in Sun's Javadoc. If you tried this already, then sorry, you must have done something wrong.

Yves.

enemorales 05-15-2007 08:20 AM

Hi,

Certainly if I use the code proposed by Seagull that works, but I do not want to do that. I want to drop the reference and then be able to create new objects --with the same content-- to retrieve the values in the Map.

theYinYeti: Could you give me some reference to look at (I mean in the javadoc)? I looked at the reference for Map and for that reason I tried overriding the equals and hashCode method. The equals is easy. I simply check that x and y are the same. For the hashCode I tried returning x*1000+y as a hashCode, but it did not work:

Code:

  // ... within class IntPair:
  public boolean equals(IntPair p) {
    return this.x == p.x && this.y == p.y;
  }

  public int hashCode() {
    return x*1000+y;
  }

Thank you again...

enemorales 05-15-2007 09:28 AM

Ok, got it. I had to define the equals method as equals(Object o) and not as equals(IntPair p).

Thank you all for the answers.


All times are GMT -5. The time now is 03:46 AM.