开发者

Which type of collection should I use for this Java problem?

开发者 https://www.devze.com 2023-03-13 08:38 出处:网络
I would like to have a bi-dimensionnal array that contains only integers. The coordinates are integers as well.

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 t开发者_开发知识库he 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.


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

Guava Table


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);
    }
}


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.


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.


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


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


List of Integer Lists would work.

List<List<Integers>

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

0

精彩评论

暂无评论...
验证码 换一张
取 消