1

I would like to have a bi-dimensionnal array that contains only integers. The coordinates are integers as well.

The problem is:

  • I don't know by advance how many cols/rows there will be.
  • I would like to fill it randomly.

Example:

Assuming the first number to be 2, placed in (3;2). I want to be able to add the 8 simply, for example like that: array.add(8,2,1);

_ _ _ _      _ _ _ _
_ _ _ _  =>  _ _ 8 _
_ _ _ 2  =>  _ _ _ 2

I already found something that was actually working, but it is really heavy. It is

Hashtable<Integer, Hashtable<Integer, Integer>>

Does anyone see a more sophisticate way to do it? I'm not that good with Collections.

SteeveDroz
  • 6,006
  • 6
  • 33
  • 65
  • @talnicolas I'm using it a few dozen times in my class. It's heavy to write, not easy to read and very painful to debug. – SteeveDroz Jun 15 '11 at 14:11
  • Then why not just try defining a wrapper class that makes it easier to read. The data structure you has seems reasonable. – Patrick Jun 15 '11 at 14:17
  • I'm sorry, I didn't think the question was that subjective, maybe someone should move it to PROGRAMMERS!? – SteeveDroz Jun 15 '11 at 14:20
  • 1: Write unit-tests that covers your implementation 2: Use whatever structure you need to support your use-case 3: That's plenty sophisticated. Elegant code is code that work – pap Jun 15 '11 at 14:27

7 Answers7

3

Maybe you could use Table from Guava This provides you table.put(R rowKey, C columnKey, V value)

Guava Table

BastiS
  • 452
  • 3
  • 11
2

You need some custom made classes in this case. How about defining a Cell class:

public class Cell implements Comparable<Cell> {
    public int row;
    public int col;

    public Cell() {
        this(0, 0);
    }

    public Cell(int row, int col) {
        this.row = row;
        this.col = col;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + this.row;
        result = prime * result + this.col;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instance of Cell))
            return false;
        Cell cell = (Cell) obj;
        return this.row == cell.row && this.col == cell.col;
    }

    //Define ordering for cells
    @Override
    public int compareTo(Cell cell) {
        int compare = cell.row - this.row;
        if (compare == 0)
            compare = cell.col - this.col;
        return compare;
    }
}

And then a Grid class which extends TreeMap to maintain a logical cell ordering:

import java.util.TreeMap;

public class Grid extends TreeMap<Cell, Integer> {
    public Integer get(int row, int col) {
        return this.get(new Cell(row, col));
    }

    public Integer put(int row, int col, Integer value) {
        return this.put(new Cell(row, col), value);
    }
}
Marcelo
  • 11,218
  • 1
  • 37
  • 51
1

Make a class that suits your needs. Or better, make an interface that declares the methods in which you want the class to be used. In your code refer to the type of the interface.

In the implementation of the interface, I would use ArrayList<ArrayList<Integer>>. Before reading or assigning a number simply check whether the coordiantes are valid. If not, you should be able to prepopulate the array with null (or other not-a-number value) before setting or reading the value.

Miki
  • 7,052
  • 2
  • 29
  • 39
1

Can't you just create a hash map that has a string key and store whatever numeric value you want? I.e.

Map<String, Integer> m = new HashMap<String,Integer>();
m.put(makeKey(3,2), 2); // where makeKey returns something like "[3,2]"

EDIT:

The downside is you don't have a reliable iteration order, i.e. if you want to iterate over everything in the Nth row or column, there's no easy way to do that efficiently.

Kevin
  • 24,871
  • 19
  • 102
  • 158
  • I'm not sure I'll take your answer for this particular problem, but I surely will use that someday!!! That's a good idea. – SteeveDroz Jun 15 '11 at 14:17
0

Check out TIntIntHashMap in Trove. Those Trove collections are very nice.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
0

I'm guessing you should be looking at 2 dimensional arrays or either arraylists since you don't know the size of them.

Lyrion
  • 426
  • 6
  • 21
0

List of Integer Lists would work.

List<List<Integers>

You can do the row and column value through the index.