Michael Michael - 4 months ago 14
Java Question

Can I create a HashMap with "relative" variables?

Let's say I have a 2D array that represents a board game. I have a list of "values" (keys) (1, 2, 3 ... 12) that represent positions in the array that are relative to the current position.

For example, in

array[1][1]
, the key 1 represents the position left
array[1][0]
while the key 2 might represent the position left and above it array
[0][0]
.

Is there any way to store these two data (I'd like to avoid a bunch of if-statements every time I use the values) in a HashMap? Or, in any data structure? Is this the right time to create an enum?

I tried this, which clearly doesn't work.

int row = 3;
int col = 5;
HashMap<Integer,String> markMap = new HashMap<>();
markMap.put(1,"col-1");
String location = markMap.get(1);
grid[row][(int)location] = 500;

Answer

Great suggestions so far. Building off of everyone else, you can also create an enum of offsets

enum Direction {
    LEFT(-1, 0),
    UPPERLEFT(-1, -1),
    DOWN(0, - 1),
    ...;

    public final int xoffset;
    pubiic final int yoffset;

    Direction(int xoffset, int yoffset) {
        this.xoffset = xoffset;
        this.yoffset = yoffset;
    }

    public static GridObject getRelativeItem(GridObject[][] grid, int x, int y, Direction dir) {
        return grid[x + dir.xoffset][y + dir.yoffset];
    }

    public static void setRelativeItem(GridObject[][] grid, int x, int y, Direction dir, GridObject newValue) {
        grid[x + dir.xoffset][y + dir.yoffset] = newValue;
    } 
}

If you stick with this design, you can access grid items by calling (if you wanted to access the left of (1, 1)

Direction.getRelativeItem(grid, 1, 1, LEFT)

To set, you can likewise call this to set value:

Direction.setRelativeItem(grid, 1, 1, LEFT, myValue)

Though this is awkward and admittedly reeks of poor abstraction. Alternatively you can define getters for the offsets (add instance methods xoffset and yoffset that just return the private variable values). Then you would have static objects LEFT, UPPERLEFT, DOWN much like cricket_007's solution. In this case if you wanted to get a value, you can call

grid[x + LEFT.xoffset()][y + LEFT.yoffset()]

to set

grid[x + LEFT.xoffset()][y + LEFT.yoffset()] = myValue;

By definition, you cannot instantiate an enum yourself. Enums are initialized by the JVM, and there are only a fixed number of them (in this case LEFT, UPPERLEFT, DOWN...).

Comments