создание вложенного хэш-карты из текстового файла: не все данные сохранены, возможно, перезаписаны

1

Мне нужно прочитать два файла, добавить их в hashmap и провести сравнение. Это большой файл, чтобы сделать это вручную. Вот мой код Java:

 /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws FileNotFoundException, IOException {
        // TODO code application logic here
        BufferedReader in1 = new BufferedReader(new FileReader("comparetheresults/595231gov_nov_13_assessed.txt"));
        BufferedReader in2 = new BufferedReader(new FileReader("comparetheresults/627231farsidetect.txt"));

          HashMap<String, HashMap<String, ArrayList<String>>> hmap1 = new HashMap<String, HashMap<String, ArrayList<String>>>();
          HashMap<String, HashMap<String, ArrayList<String>>> hmap2 = new HashMap<String, HashMap<String, ArrayList<String>>>();
          ArrayList<String>  rel= new ArrayList<String>();
          String Id = null;


         String line = null;
         String relation = null;
         while ((line = in1.readLine()) != null){
             if(line.contains("ID:")){
                 hmap1.put(line, new HashMap<String, ArrayList<String>>());
                 Id = line;
             }
             else if(line.contains("Relation:")){
                 relation = line;
             }
             else if(line.contains("Result:")){
                 if(rel == null)
                    rel= new ArrayList<>();
                 rel.add(line);
                 hmap1.get(Id).put(relation, rel);
             }
             else if(line.contains("TP") || line.contains("FP") || line.contains("TN") || line.contains("FN")){
                 rel.add(line);
                 hmap1.get(Id).put(relation, rel); 
                 rel = null;
             }

         }

        for (Object e : hmap1.entrySet()) {
            System.out.print(e);
        }
        System.out.println();



        in1.close();
        in2.close();
    }

}

Вот формат прочитанного файла

ID: 01
Приговор: бла-бла-бла
Связь: бла-бла
Результат: abc
Теннесси

ID: 01
Приговор: бла-бла-бла
Связь: бла-бла
Результат: xyz
FP

ID: 02
Приговор: бла-бла-бла
Связь: бла-бла
Результат: бла-бла
FP

Проблема в том, что я могу увидеть только одну запись каждого идентификатора в результате. Другие данные могут быть переписаны. Что-то не так, я сделал, в формате hashmap?

Помоги пожалуйста.

Благодарю.

  • 0
    HashMap может содержать только один объект на ключ, поэтому сохраняется только последнее значение, найденное для каждого ключа; каждый раз, когда вы добавляете новое значение с тем же ключом, оно заменяет предыдущее. Если вам нужно несколько значений для каждого ключа, вам нужно использовать MultiMap или Map<String,List<String>> и управлять значением списка самостоятельно.
Теги:
hashmap
overwrite

1 ответ

0
Лучший ответ

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

Вы проверяете, находится ли Result: на карте и добавляет результат в ArrayList, хранящийся в ключе, указанном в Relation: но вы не проверяете, существует ли идентификатор уже на карте перед созданием нового HashMap,

Эта строка - это то, что переписывает ваши данные для каждого идентификатора

if(line.contains("ID:")){
     hmap1.put(line, new HashMap<String, ArrayList<String>>());
     Id = line;
}

Если строка содержит ID: вы создаете новый HashMap при любом ключе, определенном в ID: даже если его уже существует.

Если вы хотите добавить данные, уже сохраненные в этом ключе, вам нужно сделать то же самое, что и вы, с логикой для Result:

if(line.contains("ID:")){
    if ( hmap1.containsKey(line) ) {
        // get the entry and do something with it
    }
    else { 
        hmap1.put(line, new HashMap<String, ArrayList<String>>());
    }
    Id = line;
}

Кроме того, кажется, что у вас небольшая проблема с обработкой поля Result: в том, что вы делаете что-то нечетное с ArrayList для хранения результатов. Как он закодирован, это не похоже на то, что вы хотите. Предположим, что у вас есть результат, и вы добавили его в новый список, а затем позже вы хотите добавить что-то еще в список результатов, вы никогда не получите список из HashMap, чтобы добавить его, вы просто создаете новый ArrayList каждый время.

Попробуйте это вместо этого:

else if(line.contains("Result:")){
    // check if the key exists in the map, or if the value is null
    if( !hmap1.get(Id).containsKey(relation) || hmap1.get(Id).get(relation) == null ) {
        rel = new ArrayList<>(); // make new list
    }
    // otherwise, get the list from your map
    else {
        rel = hmap1.get(Id).get(relation); // get the result list
    }
    // add result to the list
    rel.add(line); 
    // add the list to the map...
    hmap1.get(Id).put(relation, rel);
}

Надеюсь это поможет.

  • 0
    Для того же идентификатора мне нужно добавить разные отношения, и для каждого отношения будет список, содержащий 2 значения / строки в качестве результатов. Будет ли это делать работу?
  • 0
    Это, безусловно, поможет вам начать. Я не знал, что вы хотите сделать, поэтому я не заполнял детали реализации. Если вы не перезаписываете свой идентификатор новым хеш-картой, не проверив сначала, что он существует, вы можете получить значение этого идентификатора позже и делать то, что вам нужно. Если посмотреть на ваш код, похоже, он должен работать, за исключением небольшой отладки, чтобы убедиться ...
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню