Мне нужно прочитать два файла, добавить их в 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
FPID: 02
Приговор: бла-бла-бла
Связь: бла-бла
Результат: бла-бла
FP
Проблема в том, что я могу увидеть только одну запись каждого идентификатора в результате. Другие данные могут быть переписаны. Что-то не так, я сделал, в формате hashmap?
Помоги пожалуйста.
Благодарю.
Ваша проблема в том, что у вас есть файл, в котором один и тот же идентификатор существует несколько раз, и вы неправильно обрабатываете тот факт, что это может быть так.
Вы проверяете, находится ли 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);
}
Надеюсь это поможет.
HashMap
может содержать только один объект на ключ, поэтому сохраняется только последнее значение, найденное для каждого ключа; каждый раз, когда вы добавляете новое значение с тем же ключом, оно заменяет предыдущее. Если вам нужно несколько значений для каждого ключа, вам нужно использовать MultiMap илиMap<String,List<String>>
и управлять значением списка самостоятельно.