Java выпадает элемент <List>

196
19 сентября 2017, 06:31

Добрый день. Есть хеш объектов вида:

HashMap <String, Question> hashQuestionAnswers = new HashMap<String, Question>();

Введён для обеспечения уникальности, на случай совпадения объектов. Сам класс выглядит так:

public class Question extends BaseNode implements BaseInternalElementsNode{ 
    private String text;
    private List<Answer> answers;

Родительский класс имеет следующие важные поля:

public abstract class BaseNode {
    private String idNode; // определяем имя ID элемента и его значение.
    private String nodeName; // определяем имя ноды <nodeName ...>

Методы интерфейса не принципиальны - они направлены на работу с XML-кой.

Класс Answer :

public class Answer {
    private String id;
    private String text;

Собственно, для ключа hashQuestionAnswers используется idNode родительского класса BaseNode (он сделан уникальным). Собственно в чём проблема. Поочерёдно перебирая объекты Question двух списков столкнулся с проблемой, что в какой-то момент похожие(не одинаковые!) замещают друг-друга. Из-за чего вся работа идёт на смарку. Вот участок кода, который описывает этот момент:

Question resultQuestion = exam.checkQuestionWithAnswer();
if (resultQuestion!=null){
    addLineToConsole("Add to hashQuestionAnswers question id: " + resultQuestion.getIdNode() + ". " + resultQuestion.getText());
    addLineToConsole("First answer id: " + resultQuestion.getAnswers().get(0).getId() + ". " + resultQuestion.getAnswers().get(0).getText());
    addLineToConsole("Add to hashQuestionAnswers question id: " + resultQuestion.getIdNode());
    hashQuestionAnswers.put(resultQuestion.getIdNode(), resultQuestion);
    addLineToConsole("............................\nCheck hashQuestionAnswers{}...");
    checkHashQuestionsResultWA(hashQuestionAnswers);
    addLineToConsole("............................\n");
    unknownQuestion=false;
}

Что было понятно приведу лог, который выводит addLineToConsole() при добавлении в хэшмап нового объекта. Сразу скажу, что объекты полностью совпадают кроме nodeId и у вложенных списков Answer отличается id

первый объект

............................ Check hashQuestionAnswers{}... size hashMapQuestions: 1
---------------------CHECK HM--------------------- 
Question: q1 (q1). text1
 - answer: q1_1. answer1
--------------------- FINISH --------------------- 
............................

Появляется второй объект

............................ Check hashQuestionAnswers{}... size hashMapQuestions: 2
---------------------CHECK HM--------------------- 
Question: q1 (q1). text1
 - answer: q1_1. answer1 
Question: q2 (q2). text2
 - answer: q2_2. answer2
--------------------- FINISH ---------------------
............................

Третий объект

............................ Check hashQuestionAnswers{}... size hashMapQuestions: 3
---------------------CHECK HM--------------------- 
Question: q1 (q1). text1
 - answer: q1_1. answer1 
Question: q2 (q29). text29 similar as text2
 - answer: c29_2. answer29 similar as answer2 
Question: q29 (q29). text29 similar as text2
 - answer: q29_2. answer29 similar as answer2
--------------------- FINISH ---------------------
............................

Четвёртый объект

............................ Check hashQuestionAnswers{}... size hashMapQuestions: 4
---------------------CHECK HM--------------------- 
Question: q1 (q1). text1
 - answer: q1_1. answer1 
Question: q2 (q29). text29 similar as text2
 - answer: q29_2. answer29 similar as answer2 
Question: q29 (q29). text29 similar as text2
 - answer: q29_2. answer29 similar as answer2 
Question: q30 (q30). text30
 - answer: q30_1. answer30
--------------------- FINISH --------------------- 
............................

Т.е. как видите, при добавлении похожего объекта, происходит замещение более раннего объекта на него. Они могут идти как друг за дружкой, так и на дистанции в сотню объектов. Порядок не принципиален. Никак не могу понять, почему q29 подменяет q2 если они не равны, не одинаковы. List тоже не спасает - там такая же ошибка лезет. Можете объяснить, почему? Ошибка где-то на поверхности, но я не могу её увидеть.

Answer 1

описал методы hashCode() и equals() Прогнал тест:

public void testHash(){
        Question question1 = new Question();
        question1.setText("qwe");
        question1.setIdNode("q1");
        System.out.println(question1.hashCode());
        Question question2 = new Question();
        question2.setText("qwe");
        question2.setIdNode("q2");
        System.out.println(question2.hashCode());
        HashMap<String, Question> hashMap = new HashMap<String, Question>();
        hashMap.put(question1.getIdNode(), question1);
        hashMap.put(question2.getIdNode(), question2);
        assertNotSame(hashMap.get(question1.getIdNode()),hashMap.get(question2.getIdNode()));
        //assertNotSame(question,question2);
        List<String> listKey = new ArrayList(hashMap.keySet());
        Collections.sort(listKey);
        for(String key: listKey){
            //for(Map.Entry<String, Question> entry : hashMapQuestions.entrySet()){
            Question question = hashMap.get(key);
            System.out.println("Question: " + key + " ("+ question.getIdNode() + "). " +  question.getText());
            for(Answer answer: question.getAnswers()){
                System.out.println(" - answer: "+ answer.getId() + ". " + answer.getText());
            }
        }
    }

тест идёт нормально, а картинка не менятется :( причём используется тот же код для вывода содержимого HashMap

Вот вывод теста:

3487426
3487427
Question: q1 (q1). qwe
Question: q2 (q2). qwe

UPD: если убрать переписанные методы hashCode() и equals(), то ничего не изменится, тест успешно будет идти.

Answer 2

В общем, проблему решил, но сути не понял. Пришлось дополнительно создавать ещё один новый объект перед записью в хэш.

if (resultQuestion!=null){
    Question question = new Question();
    question.setIdNode(resultQuestion.getIdNode());
    question.setText(resultQuestion.getText());
    question.setAnswers(resultQuestion.getAnswers());
    resultQuestion.hashCode();
    hashQuestionAnswers.put(question.getIdNode(), question);
    addLineToConsole("............................\nCheck hashQuestionAnswers{}...");
    checkHashQuestionsResultWA(hashQuestionAnswers);
    addLineToConsole("............................\n");
    resultQuestion=null;
}

на сию мысль натолкнул юнит-тест Теперь замена ушла.

READ ALSO
Как изменить формат даты в jhipster?

Как изменить формат даты в jhipster?

Дата в моем проекте

214
Вопрос по методу DateTimeFormatter.ofPattern?

Вопрос по методу DateTimeFormatter.ofPattern?

Мне необходимо преобразовать строку с датой в объект LoacalDate чтобы с ним дальше работатьПостоянно появляется сообщение: Exception in thread "main" java

177
При попытке изменить цвет одного Shape&#39;а из класса, меняются цвета всех фигур в разметке

При попытке изменить цвет одного Shape'а из класса, меняются цвета всех фигур в разметке

У меня есть десять кнопок при нажатии которых происходит сохранение значения кнопки, далее при повторном открытии активности рядом должен...

232
Всплывающие блоки по клику через js

Всплывающие блоки по клику через js

Добрый вечер, коллеги! Прошу помочь человеку, недавно начавшему изучать jsЕсть задача - некая боковая навигация, состоящая из списка со ссылками,...

174