2013-10-11 7 views
5

Dziwna rzecz dzieje się w moim kodzie i nie jestem po prostu pewna co się dzieje. Mam plik, który wygląda tak:Java List dodaje ostatni rekord, duplikuje go dla liczby rekordów w pliku

id;state;city;total_pop;avg_temp 
1;Florida;;120000;76 
2;Michigan;Detroit;330000;54 
3;New Jersey;Newark;;34 

Mój parser java powinien utworzyć listę map jako wynik i powrót. Ale jedyną rzeczą, która zostanie zwrócona, jest ostatni rekord w pliku powtarzany dla liczby wierszy w pliku. Czy ktoś może spojrzeć na mój kod i oświecić mnie, co się dzieje? Z góry dziękuję.

public class FileParserUtil { 

    public List<Map<String, String>> parseFile(String fileName, char seperator) 
      throws IOException { 

     CSVReader reader = new CSVReader(new FileReader(fileName), seperator); 
     Map<String, String> record = new HashMap<String, String>(); 
     List<Map<String, String>> rows = new ArrayList<Map<String, String>>(); 

     String[] header = reader.readNext(); 
     String[] nextLine; 

     while ((nextLine = reader.readNext()) != null) { 
      for (int i = 0; i < header.length; i++) { 
       record.put(header[i], nextLine[i]); 
      } 
      System.out.println("--------Here is the record: ---------"); 
      System.out.println(record); 
      rows.add(record); 
      System.out.println("--------Here are the rows: ---------"); 
      System.out.println(rows); 
     } 
     reader.close(); 
     return rows; 

    } 
} 

Oto wynik konsola z powyższym okresie od głównej metody ...

--------Here is the record: --------- 
{id=1, avg_temp=76, state=Florida, total_pop=120000, city=} 
--------Here are the rows: --------- 
[{id=1, avg_temp=76, state=Florida, total_pop=120000, city=}] 
--------Here is the record: --------- 
{id=2, avg_temp=54, state=Michigan, total_pop=330000, city=Detroit} 
--------Here are the rows: --------- 
[{id=2, avg_temp=54, state=Michigan, total_pop=330000, city=Detroit}, {id=2, avg_temp=54, state=Michigan, total_pop=330000, city=Detroit}] 
--------Here is the record: --------- 
{id=3, avg_temp=34, state=New Jersey, total_pop=, city=Newark} 
--------Here are the rows: --------- 
[{id=3, avg_temp=34, state=New Jersey, total_pop=, city=Newark}, {id=3, avg_temp=34, state=New Jersey, total_pop=, city=Newark}, {id=3, avg_temp=34, state=New Jersey, total_pop=, city=Newark}] 

Odpowiedz

1

to dlatego, że w HashMap nie można mieć zduplikowane wartości .. tak, to kiedy to zrobić

record.put("id","1"); 

będzie sprawdzić, czy jest już klucz o nazwie „id”, jeśli nie będzie on zastąpić jego stara wartość z nową wartością. Przy pierwszej iteracji nie zastąpi niczego, ale z kolejnej iteracji zacznie zastępować stare wartości.

A kiedy dodać

row.add(record); 

jesteś ciągle dodawanie tego samego odniesienia, a ponieważ mapa zawiera tylko nowo wstawionego wartość toString() metoda tego samego odniesienia nazywa i ta sama wartość jest ponownie drukowana i jeszcze raz.

należy dodałem

record = new HashMap<String,String>(); 

aby dodać nową mapę dla każdego rekordu.

+0

Dziękuję za wyjaśnienie. –

+0

serdecznie zapraszamy ... chciałbym również zaproponować utworzenie nowej klasy do przechowywania wartości z pliku i utworzenie nowej instancji tej klasy dla każdego rekordu. W ten sposób kod będzie znacznie czystszy. –

+0

Czy istnieje sposób, aby to przyspieszyć? Wydaje się być powolny. –

4

myślę, że zapomniał wymienić rekord z nowym pustym mapie, po dodaniu do lista. Chcesz coś takiego:

rows.add(record); 
record = new HashMap<String, String>(); 
1

ty powinien poruszać się po linii

Map<String, String> record = new HashMap<String, String>(); 

wewnątrz pętli for:

public class FileParserUtil { 

    public List<Map<String, String>> parseFile(String fileName, char seperator) 
      throws IOException { 

     CSVReader reader = new CSVReader(new FileReader(fileName), seperator); 
     List<Map<String, String>> rows = new ArrayList<Map<String, String>>(); 

     String[] header = reader.readNext(); 
     String[] nextLine; 

     while ((nextLine = reader.readNext()) != null) { 
      Map<String, String> record = new HashMap<String, String>(); 
      for (int i = 0; i < header.length; i++) { 
       record.put(header[i], nextLine[i]); 
      } 
      System.out.println("--------Here is the record: ---------"); 
      System.out.println(record); 
      rows.add(record); 
      System.out.println("--------Here are the rows: ---------"); 
      System.out.println(rows); 
     } 
     reader.close(); 
     return rows; 

    } 
} 
2
while ((nextLine = reader.readNext()) != null) { 
    Map<String, String> record = new HashMap<String, String>(); 
... 
} 

Jesteś ponowne tę samą instancję mapy wszystkich czas, wartości zostaną nadpisane. Zalecam również utworzenie osobnej klasy do przechowywania danych, byłoby to czystsze.

Powiązane problemy