1

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?

3
  • 3
    You probably didn´t override the hashCode properly as the HashMap works with this method. Commented Nov 21, 2016 at 12:35
  • 4
    Show the Question class, and show how you populate the map. You probably modify the question after it's stored in the map, thus changing its hashCode. Or you just didn't override equals() and hashCode(). Commented Nov 21, 2016 at 12:35
  • Overwrite the .equals method and hashCode method. Commented Nov 21, 2016 at 12:38

3 Answers 3

5

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()

Sign up to request clarification or add additional context in comments.

Comments

1

You must overide the hashCode method for the class which is used as a key in HashMap.

It could be as simple as :

@Override
public int hashCode() {
    return questionId.hashCode();
}

Comments

0

As other have said, the HashMap may not be able to retrieve the entry associated with your key because your Question class is missing the override of the hashCode() function (see this for reference: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()).

I would suggest to implement the function as follows:

@Override
public int hashCode() {
     return questionId.hashCode() + content.hashCode();
}

The general rule is that If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. (from the link above).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.