LinkedHashMap со значениями как вектор перезаписывается

Когда я написал этот кусок кода из-за pnValue.clear(); вывод, который я получал, был нулевыми значениями для ключей. Итак, я где-то читал, что добавление значений одной карты к другой - это просто ссылка на исходную карту, и нужно использовать метод clone(), чтобы убедиться, что две карты разделены. Теперь проблема, с которой я сталкиваюсь после клонирования моей карты, состоит в том, что если у меня есть несколько значений для определенного ключа, то они перезаписываются. Например, ожидаемый результат обработки goldSentence:

{PERSON = [James Fisher],ORGANIZATION=[American League, Chicago Bulls]}

но то, что я получаю, это:

{PERSON = [James Fisher],ORGANIZATION=[Chicago Bulls]}

Интересно, где я иду не так, учитывая, что я объявляю свои ценности как Vector<String>

for(WSDSentence goldSentence : goldSentences)
                {   
                    for (WSDElement word : goldSentence.getWsdElements()){
                        if (word.getPN()!=null){
                            if (word.getPN().equals("group")){
                                String newPNTag = word.getPN().replace("group", "organization");
                                pnValue.add(word.getToken().replaceAll("_", " "));
                                newPNValue = (Vector<String>) pnValue.clone();
                                annotationMap.put(newPNTag.toUpperCase(),newPNValue);

                            }


                            else{

                                pnValue.add(word.getToken().replaceAll("_", " "));
                                newPNValue = (Vector<String>) pnValue.clone();
                                annotationMap.put(word.getPN().toUpperCase(),newPNValue);

                            }

                        }

                        sentenceAnnotationMap = (LinkedHashMap<String, Vector<String>>) annotationMap.clone();
                        pnValue.clear();
                    }

ИЗМЕНЕННЫЙ КОД Заменен Вектор списком и удалено клонирование. Однако это все еще не решает мою проблему. Это возвращает меня к исходной точке, где мой вывод: {PERSON=[], ORGANIZATION=[]}

for(WSDSentence goldSentence : goldSentences)
        {   
            for (WSDElement word : goldSentence.getWsdElements()){
                if (word.getPN()!=null){
                    if (word.getPN().equals("group")){
                        String newPNTag = word.getPN().replace("group", "organization");
                        pnValue.add(word.getToken().replaceAll("_", " "));
                        newPNValue = (List<String>) pnValue;
                        annotationMap.put(newPNTag.toUpperCase(),newPNValue);

                    }


                    else{

                        pnValue.add(word.getToken().replaceAll("_", " "));
                        newPNValue =  pnValue;
                        annotationMap.put(word.getPN().toUpperCase(),newPNValue);

                    }

                }

                sentenceAnnotationMap =  annotationMap;

            }
            pnValue.clear();

1 ответ

Решение

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

  • Если карта содержит наш ключ, получите список и добавьте наше значение
  • В противном случае создайте новый список, добавьте наше значение и добавьте список на карту.

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

List<String> list = map.get(key);  // try to get the list
if (list == null) {                // list doesn't exist?
    list = new ArrayList<>();      // create an empty list
    map.put(key, list);            // insert it into the map
}
list.add(value);                   // update the list
Другие вопросы по тегам