Reputation: 411
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
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
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
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