简体   繁体   中英

Java how to store data from different CSV files

I wonder how to generate a class holding the values of the fields from a csv file does not establish a rigid number of fields. I read about generating classes using CodeModel, but after completing the program can not be compiled specifically to take a job with a .csv file, it needs to work on the fly. Some files have 22 fields and the other 40. The simplest solution would be to create a class with 50 fields and fill them in a for loop.

Example file:

Colname1; colname2; colname3...........
2014-23-11;22;22;22;23;4;4;5;
2014-23-11;32;22;22;23;4;4;5;
2014-23-11;62;52;22;23;4;4;5;
2014-23-11;28;22;22;93;4;4;5;

My solution:

 HashMap<String, List<String>> map = new LinkedHashMap<String, List<String>>();

        List content = reader.readAll();
        String[] row;
        String key;
        int kolumna=0;

         List<String> tmp = new ArrayList<String>();

        for(int i=0; i <columnCount-1; i++) {
            List<String> lista = new ArrayList<String>();

            key=null;
            for (Object object : content) {

                row = (String[]) object;
                if (kolumna == 0) {
                    //  map.put(row[i],null);
                    key = row[i];
                }
                if (kolumna != 0) {

                    lista.add(row[i]);
                   // System.out.println(row[i] + " # " + kolumna + key);
                    map.put(key, lista);

                }

                kolumna++;
            }

            kolumna=0;
        }

        for (Map.Entry<String, List<String>> entry : map.entrySet())
        {
           // System.out.println(entry.getKey() + "/" + entry.getValue());
        }

Its very hard to create a class at run time when you don't know the number of fields and their data types. You could do two passes though, in the first pass figure out a schema and create classes accordingly and populate in the second pass. Basically you would need to keep track of the field names, their datatypes and a keep a fallback datatype (eg. a subset of records for a particular field might be int and then suddenly you might discover a long).

Personally, I don't think making schemas at runtime provides a very clean solution. A map of maps might have been a better way to deal it. Just my two cents.

uniVocity-parsers can extract the values from all columns, no matter how many you have:

CsvParserSettings parserSettings = new CsvParserSettings();

// To get the values of all columns, use a column processor
ColumnProcessor rowProcessor = new ColumnProcessor();
parserSettings.setRowProcessor(rowProcessor);

CsvParser parser = new CsvParser(parserSettings);

//This parses the entire file and triggers the column processor
parser.parse(new FileReader(yourFile));

//Here we get the column values:
Map<Integer, List<String>> columnValuesByIndex = rowProcessor.getColumnValuesAsMapOfIndexes();
Map<String, List<String>> columnValuesByName = rowProcessor.getColumnValuesAsMapOfNames();

Disclosure: I am the author of this library. It's open-source and free (Apache V2.0 license).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM