Добрый день. Есть хеш объектов вида:
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 тоже не спасает - там такая же ошибка лезет. Можете объяснить, почему? Ошибка где-то на поверхности, но я не могу её увидеть.
описал методы 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(), то ничего не изменится, тест успешно будет идти.
В общем, проблему решил, но сути не понял. Пришлось дополнительно создавать ещё один новый объект перед записью в хэш.
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;
}
на сию мысль натолкнул юнит-тест Теперь замена ушла.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Мне необходимо преобразовать строку с датой в объект LoacalDate чтобы с ним дальше работатьПостоянно появляется сообщение: Exception in thread "main" java
У меня есть десять кнопок при нажатии которых происходит сохранение значения кнопки, далее при повторном открытии активности рядом должен...
Добрый вечер, коллеги! Прошу помочь человеку, недавно начавшему изучать jsЕсть задача - некая боковая навигация, состоящая из списка со ссылками,...