dedmar
dedmar

Reputation: 411

how make an ArrayList to solve the "issue" with LinkedHashMap?

I have managed to make a program where I would read data from excel files and store them in tables in mysql. My program read the first row of each file create the fields for the tables and store the rest data as values in each columns. Just because that happen programmatically I have choosed to read all the values using LinkedHashMap. Everything works fine. But when I finished and test my program I get an error in my console. The error is by LinkedHashMap because if the map previously contained a mapping for the key, the old value is replaced by the specified value.

The code for parsing the data is the below:

private static List<TableRow> parseExcelColumnData(List sheetData) {
        // read each row from 1 to the last
        ArrayList<TableRow> tousRows = new ArrayList<TableRow>();
        for (int rowCounter = 1; rowCounter < sheetData.size(); rowCounter++) {

            List list = (List) sheetData.get(rowCounter);

            LinkedHashMap<String, Integer> tableFields = new LinkedHashMap(list
                    .size());
            String str;
            String[] tousFields = new String[list.size()];

            int i = 0;
            Cell cell = (Cell) list.get(0); // get the first column
            long currentID = (long) cell.getNumericCellValue();
            for (int j = 0; j < list.size(); j++) { //get the rest
                cell = (Cell) list.get(j); 
                if (cell != null) {
                    if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
                        ...
                                ...............
                    }
                }
            }
            tousRows.add(new TableRow(currentID, tableFields));
        }

        return tousRows;

    }

Could anyone help how could I make the "tableFields" an ArrayList so as not to replace the old value?

Upvotes: 0

Views: 351

Answers (3)

buritos
buritos

Reputation: 598

You could use an IdentityHashMap instead.

perhaps you also need to change the calls to put(key,value) into put(new String(key), value).

Upvotes: 0

DKM
DKM

Reputation: 188

You cannot put the same key in a hash map twice. Imagine a map called 'fields' like this: "A => 1". You would access the key A with fields.get("A") and expect the value to be 1. If you now put a key A again into the map so it would be like "A => 1, A => 2". What would you expect to be the result of fields.get("A")? In this case you cannot decide whether to return 1 or 2.

The thing to do here is instead of using a map that maps string to integer, you will have to map string to integer-array. The code would look like this:

    private static List<TableRow> parseExcelColumnData(List<?> sheetData) {
        // read each row from 1 to the last
        ArrayList<TableRow> tousRows = new ArrayList<TableRow>();
        for (int rowCounter = 1; rowCounter < sheetData.size(); rowCounter++) {

            List<?> list = (List<?>) sheetData.get(rowCounter);

            LinkedHashMap<String, List<Integer>> tableFields = new LinkedHashMap<String, List<Integer>>(list.size());
            String str;
            String[] tousFields = new String[list.size()];

            int i = 0;
            Cell cell = (Cell) list.get(0);
            long currentID = (long) cell.getNumericCellValue();
            for (int j = 0; j < list.size(); j++) {
                cell = (Cell) list.get(j); 
                if (cell != null) {
                    if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
                        put(tableFields, String.valueOf(cell.getNumericCellValue()), cell);
                    } else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
                        put(tableFields, cell.getStringCellValue(), cell);
                    } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
                        put(tableFields, String.valueOf(cell.getBooleanCellValue()), cell);
                    } else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
                        put(tableFields, cell.getStringCellValue(), cell);
                    }
                }
            }
            tousRows.add(new TableRow(currentID, tableFields));
        }

        return tousRows;

    }

    private static void put(LinkedHashMap<String, List<Integer>> tableFields, String cellValue, Cell cell) {
        if (!tableFields.containsKey(cellValue)) {
            tableFields.put(cellValue, new ArrayList<Integer>());
        }

        tableFields.get(cellValue).add(cell.getCellType());
    }

You would then have a map looking like this "A => [1, 2]".

Upvotes: 1

Paolof76
Paolof76

Reputation: 909

TRy with an object

class MyModel {
   String first;
   Integer second;
}

and then create an ArrayList like this:

List<MyModel> tableFields = new ArrayList<MyObject>(list.size());

Upvotes: 0

Related Questions