Adam Varhegyi Adam Varhegyi - 19 days ago 4
Java Question

HashMap doesnt find value by key - why?

I have a class:

Question


It has
id
and
content
.

I have a
HashMap
with
Questions
as keys and
asnwers(Strings)
as values.

I try to lookup an answer from my map, using a
Question
for key.

However it always gives null value and I don't know why because the map does contains my Question.

Code:

Log.i("info", "map:");
Log.i("info", questionAnswers.toString());
Log.i("info", "================================");

Log.i("info", "question we are looking for:");
Log.i("info", question.toString());
Log.i("info", "================================");

Log.i("info", "anwer is null: " + questionAnswers.get(question));
Log.i("info", "================================");

Iterator it = questionAnswers.entrySet().iterator();

//Iterating the map just to get information for test's sake
while (it.hasNext()) {

Map.Entry<Question, String> entry = (Map.Entry<Question, String>) it.next();

//Question in the map
Question questionInCont = entry.getKey();

//Testing the equals method
if (questionInCont.equals(question)) {


Log.i("info", "================================");
Log.i("info", "question we are looking for is equals to a question in the map");
Log.i("info", questionInCont.getQuestionId() + " == " + question.getQuestionId());

String answer = questionAnswers.get(question);

//Great, equals working but still no answer back, only null
Log.i("info", "anwer is still null: " + answer);
Log.i("info", "================================");
}
}


Log output:

11-21 13:22:13.083: I/info(18350): map:
11-21 13:22:13.083: I/info(18350): {Question{questionId='9', content='What is your name?'}=John, Question{questionId='8', content='How old are you?'}=33}
11-21 13:22:13.083: I/info(18350): ================================
11-21 13:22:13.083: I/info(18350): question we are looking for:
11-21 13:22:13.084: I/info(18350): Question{questionId='8', content='How old are you?'}
11-21 13:22:13.084: I/info(18350): ================================
11-21 13:22:13.084: I/info(18350): anwer is null: null
11-21 13:22:13.084: I/info(18350): ================================
11-21 13:22:13.084: I/info(18350): ================================
11-21 13:22:13.084: I/info(18350): question we are looking for is equals to a question in the map
11-21 13:22:13.084: I/info(18350): 8 == 8
11-21 13:22:13.084: I/info(18350): anwer is still null: null
11-21 13:22:13.084: I/info(18350): ================================





So as you can see:




  1. My HashMap does contain the question Im looking for.

  2. It does have an answer (value)

  3. The questions equals method does returns true when both questions have the same id.



E D I T :

Thanks for the comments, my question class does not have
hashCode()
function.
Is it the problem?

Question class:


public class Question implements Serializable {

String questionId;
String content;


public Question(String id, String content) {
this.questionId = id;
this.content = content;
}


@Override
public boolean equals(Object obj) {

if (obj instanceof Question) {
Question question = (Question) obj;
return questionId.equals(question.getQuestionId());
}

return false;
}
}


Sow why why I got null as the answer?

Answer

Your main problem is that you only implement the equals() method. This is strictly forbidden for values of a HashMap because equals() always has to be implemented together with hashCode().

Every entry (m1) and a second entry (m2) in a HashMap the following must be true: m1.equals(m2) implies that m1.hashCode()==m2.hashCode()