Установка Hashmap в цикле - PullRequest
       42

Установка Hashmap в цикле

0 голосов
/ 03 марта 2010

У меня есть следующий код:

Map<String, ObjectType> objectMap = new HashMap<String, ObjectType>();
for (ObjectType obj : objects) {
    obj.setSomeProperty("property value");
    objectMap.put(obj.getADiffProperty(), obj);
}

Кажется, что во время итерации цикла некоторые свойства obj изменяются для ключей, отличных от того, который установлен в данный момент. Есть ли проблема с приведенным выше кодом? Каким-то образом ссылка на obj перерабатывается циклом for?

Также этот цикл также находится во внешнем цикле.

Обновление
Я предоставляю полный метод ниже. Фактическое место, где я наблюдаю поведение, описанное выше, находится на внешней карте, определенной как Map<String, Map<String, GlossaryTerm>> loadedTerms = new HashMap<String, Map<String, GlossaryTerm>>();, определенной в классе Singleton.

List<Audience> audiences = ContentAccess.getAudienceList();

List<GlossaryTerm> glossaryTerms = ContentAccess.getAllReplacementCIs();                            

for (Audience audience : audiences) {                   
    Map<String, GlossaryTerm> termMap = new HashMap<String, GlossaryTerm>();
    for (GlossaryTerm term : glossaryTerms) {
       String definition = term.getProductGlossary().get(audience.getName());
       if (definition != null)
           term.setDefinition(definition);
       termMap.put(term.getPhrase(), term);
   }                        
   loadedTerms.put(audience.getChannelId(), termMap);
}

Ответы [ 5 ]

2 голосов
/ 03 марта 2010

Кажется, что во время итерации цикла некоторые свойства obj изменяются для ключей, отличных от того, который установлен в данный момент. Есть ли проблема с приведенным выше кодом? Каким-то образом ссылка на obj перерабатывается циклом for?

Переменная obj будет установлена ​​на «следующий» элемент итератора для objects каждый раз вокруг цикла. Если вы видите одно и то же значение ссылки в obj более одного раза, это может быть только потому, что:

  • ссылочное значение действительно появляется более одного раза в коллекции, массиве или чем-либо еще, заданном objects или

  • что-то в setSomeProperty или getADiffProperty или что-то еще, что вы делаете в цикле, обновляет objects как побочный эффект, или

  • объект objects имеет ошибочную реализацию итератора.

Другая возможность состоит в том, что вы видите разные объекты с одинаковыми значениями adiff.

Чтобы сказать больше, мне нужно увидеть больше исходного кода, чем предоставленный вами упрощенный фрагмент.

РЕДАКТИРОВАТЬ - предоставленный вами дополнительный код не выявил проблему. (Я думаю, что мы можем отклонить любые теории, связанные с обновлением списков, пока они повторяются, или странные побочные эффекты от сеттеров.)

Я подозреваю, что один из тех списков, которые предоставляет синглтон, содержит дубликаты или что-то еще неожиданное. Это может быть то, что вызывает вашу проблему.

Делайте то, что предлагает @Carl, и используйте traceprints и / или отладчик, чтобы выяснить, что находится в синглтоне Collection и что на самом деле делает ваш код.

РЕДАКТИРОВАТЬ 2 - Тот факт, что сборщик является одноэлементным классом, вероятно, не имеет значения. И содержимое HashMap НЕ изменяется случайно или спонтанно. (И в вашем коде нет маленьких зеленых демонов, которые сговорились бы заставить его потерпеть неудачу. Поверьте мне!)

У вас, похоже, есть разум, чтобы угадать, в чем проблема, и вносить изменения на основе этих предположений в надежде, что они решат проблему. Хватит гадать! Это неправильный подход, который, вероятно, только усугубит ситуацию. Вам нужно аккуратно и методично отладить код, собрать убедительные доказательства того, что на самом деле делает ваша программа, и тщательно интерпретировать эти доказательства ... не прибегая к сумасшедшим представлениям о том, что что-то меняет случайным образом.

РЕДАКТИРОВАТЬ 3 - Если бы я был в вашей ситуации, я бы попросил другого опытного Java-программиста в команде сесть со мной и помочь мне отладить код. Мне все еще иногда приходится делать это самому, и у меня было более 10 лет опыта в Java и более 30 лет опыта программирования. Иногда у вас возникает ментальный блок по проблеме, и ответом является свежий взгляд / свежий подход.

Не стыдно признаться своей команде / боссу, что вы не в своей тарелке и нуждаетесь в помощи.

2 голосов
/ 03 марта 2010

Я не думаю, что то, что вы думаете, происходит, происходит. Ссылка на объект - это то, чем она должна быть для каждой итерации. Я думаю, что должно происходить что-то еще - что свойства меняются в другом месте или не имеют значений, которые, как вы думаете, они имеют изначально. Вставьте несколько printlns, чтобы отследить, что на самом деле происходит. Код, который вы показали, не может изменить неправильные свойства.

1 голос
/ 04 марта 2010

Я начинаю новый ответ, потому что - ну, это новая мысль здесь, и дискуссия становилась довольно длинной.

Вы не сказали (я думаю), когда произойдут изменения. Но вы (потенциально) помещаете один и тот же термин в несколько карт для разных аудиторий. Ничего общего с переменной цикла - просто вы постоянно используете один и тот же список терминов для каждой аудитории. Но когда вы помещаете термин в карту, вы также меняете его определение. Но определение (потенциально) отличается для каждой аудитории. Итак, конкретный пример:

Термин A имеет определение «x» для аудитории X и «y» для аудитории Y. У вас есть обе аудитории. Вначале мы встречаемся с аудиторией X, поэтому A получает определение «x». А добавляется на карту для этой аудитории. Теперь перейдем к следующей аудитории, и изменим определение для A на "y" . Это меняет A везде, где у вас есть ссылка, в том числе на карте для аудитории X. Это объясняет, почему создание копии устраняет проблему. Это то, что вы испытываете?

0 голосов
/ 03 марта 2010

Откуда код называется? Может быть, есть параллельные проблемы? Есть ли другие темы (это веб-приложение?), Обращающиеся к ContentAccess? И я надеюсь, GlossaryTerm это простой Dto, верно?

0 голосов
/ 03 марта 2010

Это может быть просто ошибкой опечатки. В вашем фрагменте не объявлено object, но ваш put вызов использует object.getADiffProperty() вместо obj.getADiffProperty() Это намеренно?

...