1

I have found similar questions, but none of them have really helped me so far (which probably means I am doing something wrong, which is why I'm here).

I have a HashMap Map<Integer, List<Book>> that is supposed to have a Student's ID as the key and the list of Book he has in his possession as the value. Although only passing the ID as the key works, I feel like it isn't an object-oriented enough approach and that I should use Student as the key (so it'd look like so: Map<Student, List<Book>>). I tried to use it, but then I got a bunch of errors when I tried to return a given Student's list of Book, most likely because the Student wasn't found. My professor suggested me to @Override Java's hashCode and equals methods, which makes sense, since that's how HashMap compares keys, but I haven't had success in that (I am not sure what exactly I need to compare in order to see if two Student are the same; supposedly, their ID alone should work). Here are the overridden methods:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + id;
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Student other = (Student) obj;
    if (id != other.id)
        return false;
    return true;
}

What am I doing wrong? Any light you could shed on this would be extremely helpful. Thanks in advance!

2
  • 3
    The error is elsewhere. Post a complete minimal example reproducing the problem. Commented Mar 11, 2017 at 14:26
  • if (id != other.id) return false; return true; Why did you prefer this to return id.equals(other.id);? Commented Mar 11, 2017 at 16:33

1 Answer 1

1

The error seems to be in your equals method, provided your id has values outside integer caching range i.e. -128 - 127

 if (id != other.id) // <-- Error
        return false;

From your example, it seems like id is an Integer object

== checks whether the references are equal, i.e. whether they point to the same object.

For primitive types, == checks whether the values are equal.

java.lang.Integer is a reference type. int is a primitive type.

Although in case of Integer, == only works for numbers between -128 and 127 as JVM caches those values

You need to change it to

if (!id.equals(other.id))
            return false;
Sign up to request clarification or add additional context in comments.

9 Comments

Possible, but as those look like auto-generated methods I'd guess that id is a primitive.
As the OP has used an Integer as a key in the map, makes me believe that id is an Integer instance
if (!id.equals(other.id)) return false; Why did you prefer this to return id.equals(other.id);?
@LewBloch could work well for now, but as soon as you add more fields for comparison in your equals method, you will have to change the statement return id.equals(other.id); otherwise remaining comparison statements will not be executed. Hence, the correct form is better from code extensibility point of view
That wasn't the case here, but let's say that instead of the non-object-oriented id we use three name parts, we could just use: boolean is = first.equals(other.first) && second.equals(other.second) && third.equals(other.third);. I agree that sometimes if chains are better, but very few equality comparisons of value types involve more than three fields.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.