1

Possible Duplicate:
Overriding equals and hashCode in Java

package testpack;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class TestEm {

    private String company;
    private int salary;

    TestEm(String company, int salary) {
        this.company = company;
        this.salary = salary;
    }

    public static void main(String[] args) {

        Map<TestEm, String> map = new HashMap<TestEm, String>();
        map.put(new TestEm("abc", 100), "emp1");
        map.put(new TestEm("def", 200), "emp2");
        map.put(new TestEm("ghi", 300), "emp3");

        Set<TestEm> set = map.keySet();
        Iterator<TestEm> it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        **System.out.println(map.get(new TestEm("ghi", 300)));**

    }

    @Override
    public boolean equals(Object o) {

        if (o == this)
            return true;
        if (!(o instanceof TestEm))
            return false;

        TestEm te = (TestEm) o;
        return te.company.equals(company) && te.salary == salary;
    }

    @Override
    public int hashCode() {

        int code = 0;

        code = salary * 10;
        return code;
    }

    /*
     * @Override public String toString() {
     * 
     *    return this.company;  }
     */
}

and the output is

testpack.TestEm@3e8
testpack.TestEm@7d0
testpack.TestEm@bb8
emp3

Hi, i have overridden some methods of Object class in my TestEm class, everything is okay but first three outputs are using iterator and then doing a S.O.P and the last one is simply with S.O.P, i just want to know that why first three outputs are coming as objects using iterator and the 4th one simply the correct output as value corresponding the key, i have not overridden toString() so first three outputs are right but then without toString() how S.O.P is showing the correct output.

Community
  • 1
  • 1
Paritosh Ahuja
  • 1,239
  • 2
  • 10
  • 19
  • 1
    What do you mean by "S.O.P."? (This isn't an acronym I'm familiar with...) – Jon Skeet Jan 24 '13 at 13:44
  • 2
    @JonSkeet at a guess `System.out.println` – Ian Roberts Jan 24 '13 at 13:47
  • @Jon yes it is System.out.println(), i believe its pretty common acronym :p – Paritosh Ahuja Jan 24 '13 at 13:54
  • @ParitoshAhuja: The fact that I haven't come across it often enough to recognize it despite answering over 6000 questions tagged "java" suggests it's not *that* common. I think it would be clearer to just write "printing" instead of "doing a S.O.P.". – Jon Skeet Jan 24 '13 at 14:02
  • It's also not clear what the question is - why do you believe that `toString()` is relevant, and as you've overridden `equals` and `hashCode` why would you expect the final output to be *incorrect*? – Jon Skeet Jan 24 '13 at 14:03
  • okay, i will prefer writing printing instead of S.O.P :) , talking about this question, if i wont override toString() then i wont get correct output using Iterator because iterator as said by NPE, iterates over the entire object so at the output i get entire object but i wanted to have name or salary or combination of both that was possible only with toString(). – Paritosh Ahuja Jan 24 '13 at 14:09
  • 1
    Not really - it's that with the iterator you're printing the keys from the map; in the last case you're printing the value in the map. It's not a matter of "the entire object"... (If you change to use `values()` instead of `keySet()` you'll get the "emp1", "emp2", "emp3".) – Jon Skeet Jan 24 '13 at 14:14
  • yep yep got that thanks for the help :) – Paritosh Ahuja Jan 24 '13 at 14:27
  • This question is not about hashCode and equals. It is about the semantics of a Map. – Raedwald Jul 06 '14 at 12:27

4 Answers4

3

The iterator iterates over the objects in the set, whereas

map.get(new TestEm("ghi", 300))

returns the value associated with the above key. That value is "emp3".

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • and the objects in the set are the keys of the map (I know that's fairly obvious, but it seemed to be worth mentioning anyway :p) – keyser Jan 24 '13 at 13:45
1

The iterator is traversing and printing the keys (class: TestEm), whereas the S.O.P on the outside is retrieving a value of the map, corresponding to the key TestEm("ghi", 300), which happens to be "emp3" (class: String). They're different objects, hence the value printed is different.

You should override toString() in TestEm to see more clearly what's happening, something like this:

@Override
public String toString() {
    return company + " " + salary;
}
Óscar López
  • 232,561
  • 37
  • 312
  • 386
0

The fourth line is printed outside the loop and is the value returned from the map.

As you have overridden equals and hashCode, the new TestEm object you built is considered equal to the last one you added to the map.

Dan D.
  • 32,246
  • 5
  • 63
  • 79
0

You're iterating over the keys, not over the values.

Sebastian Krysmanski
  • 8,114
  • 10
  • 49
  • 91