Reputation: 45
Hello and thank you for reading. I've got a problem with a Hashmap in Java. The HashMap is thought to replace a2D array, so that the array index pair is used to caluculate the key. The map is filled in a double for-loop. The relevant code snippets are shown below.
Here is the "filling" of the map and subsequent size test.
HashMap<Integer, Cell> field = new HashMap<Integer, Cell>();
// Fill field object with cells
for (int colCnt = 0; colCnt < cols; colCnt++) {
for (int rowCnt = 0; rowCnt < rows; rowCnt++) {
Cell cell = new Cell(colCnt, rowCnt);
field.put(cell.hashCode(), cell);
}
}
System.out.println("cells: "+field.size());
Here the constructor of the Cell object:
public Cell(int column, int row) {
if (row < 0 || column < 0) {
throw new IllegalArgumentException("Cell must not have negative coordinates");
}
this.row = row;
this.column = column;
this.status = false;
}
And here the method for the HashCode (from Cell class):
public int hashCode() {
return Objects.hash(column, row);
}
where the parameters column and row refer to the local final int variables, which are class fields, set in the constructor.
The problem is: As soon as the column parameter is larger than 1 and (simultaneously) the row parameter is larger than 31 as well as larger than the column parameter, not all cells are mapped any more. Having a closer look, I found out, that only the last column (when col > 1) has full row number. All columns expect the last one are truncated to 31 elements. However, if the column parameter is much larger than rows all is fine, e.g. 1000 columns and 5 rows result in 5000 cells. On the other hand 5 columns and 1000 rows give just 1124 cells. If columns and rows are increased simultaneously, it works until 31 columns and 31 rows rsulting in 961 cells. With 32 columns and 32 rows I get 993 cells instead of 1024.
Can anybody give me some hint, what's wrong? HashMap ist set up with default paras, means initally 16 fields and load 0.75.
Thank you very much!!
Upvotes: 0
Views: 246
Reputation: 1527
A hashCode is not a unique identifier so it cannot be relied upon to serve as a Map key. A simple option is to concatenate the column and row as a String and using a Map<String,Cell>.
public class Cell {
... stuff ...
public String key() {
return String.format("%d-%d", column, row);
}
}
Upvotes: 2