在Java中,哪种数据结构最适合实现二维数组?

8

我想实现一个类似于二维数组的东西。

什么数据结构最适合这个需求呢?数组或其他数据结构都可以。如果有其他满足我的需求的数据结构,请告诉我。

我不想使用数组,因为二维数组需要在程序早期声明,但它不是固定的;大小将在运行时确定。

此外,行数将等于列数;这是固定的,因为行和列将被赋予相同的名称。

我还想遍历这个二维数据结构,就像遍历Map一样。


1
很难确定你真正想做什么...如果给出的答案不令人满意,尝试改进问题的措辞,可能添加一些示例代码以展示您如何使用2D数据结构。 - David Z
@Young:我尝试重新表述了你的问题。如果我猜错了你的意思,请再次编辑它。 - Michael Myers
4个回答

7

听起来你想要使用行键、列键和该位置的值。没有内置的数据结构可以为你完成这个任务。

最简单的方法可能是使用二维数组来存储实际数据。使用以下内容将行或列名称转换为数组中的实际索引。添加尽可能多的名称到索引绑定。

Map<String, Integer> rows = new HashMap<String, Integer>();
Map<String, Integer> cols = new HashMap<String, Integer>();

然后在网格中获取该值...
grid[rows.get("Row name")][cols.get("Column name")];

如果你想要一个更加清晰的API,可以将网格和get(String rowName, String colName)方法放在一个类中。
编辑:我看到问题已经更新了,看起来行和列的名称到索引对是相同的。因此,这是一个更新版本:
class SquareMap<V> {
    private V[][] grid;
    private Map<String, Integer> indexes;

    public SquareMap(int size) {
        grid = (V[][]) new Object[size][size];
        indexes = new HashMap<String, Integer>();
    }

    public void setIndex(String name, int index) {
        indexes.put(name, index);
    }

    public void set(String row, String col, V value) {
        grid[indexes.get(row)][indexes.get(col)] = value;
    }
    public V get(String row, String col) {
        return grid[indexes.get(row)][indexes.get(col)];
    }
}

你的程序看起来更加清晰和高效,但是我还没有理解如何使用网格。我该如何在我的程序中使用这个网格? - AGeek
你好,请问您能否解释一下这个网格的功能是什么?我该如何在其中存储数值? - AGeek

1

如果大小在运行时确定,那就不是问题。这个可能会起作用:

final int[][]              data;
final int                  size;
final Map<String, Integer> names;

// code that sets the size variable
names = new HashMap<String, Integer>();
data  = new int[size][size];

names.put("ID-A", 0);
names.put("ID-B", 1);

data[names.get("ID-A")][names.get("ID-A")] = 39;
data[names.get("ID-A")][names.get("ID-B")] = 40;
data[names.get("ID-B")][names.get("ID-A")] = 41;
data[names.get("ID-B")][names.get("ID-B")] = 42;

好的,我想要它像这样... 我希望每一行和每一列都有一个名称,以便稍后可以进行映射... 由于Java.util包中的Map数据结构中有一个键... 是否还有其他方法... - AGeek

0
你可以使用类似 Map 的数据结构。
class TwoDArray<V> implements Iterable<Map.Entry<Point, V>> {
    private final Map<Point, V> map = new LinkedHashMap<Point, V>();
    public V set(int x, int y, V value) {
       return map.put(new Point(x,y), value);
    }
    public V get(int x, int y) {
       return map.get(new Point(x, y));
    }
    public Iterator<Map.Entry<Point, V>> iterator() {
       return map.entrySet().iterator();
    }
}

// to iterate
TwoDArray<Double> twoDArray = new TwoDArray();
twoDArray.set(3, 5, 56.0);
twoDArray.set(-1000, 5, 123.4);
twoDArray.set(789012345, -100000000, -156.9);
for(Map.Entry<Point, Double> entry: twoDArray) {
  //
}

0

数组可以在运行时调整大小。如果您有一个不太经常变化的行/列大小,并且数据不太稀疏,那么数组是您最好的选择。

class TwoDimArray {
    public int[][] createArray(int nRows, int nCols) {
        return new int[nRows][nCols];
    }
    public int[][] resizeArray(int[][] oldArray, int nRows, int nCols) {
        int[][] newArray = new int[nRows][nCols];
        for (int i=0; i<Math.min(oldArray.length, nRows); ++i)
            for (int j=0; j<Math.min(oldArray[i].length, nCols); ++j)
                newArray[i][j] = oldArray[i][j];
        return newArray;
    }
}

好的,我想要它像这样... 我希望每一行和每一列都有一个名称,以便稍后可以进行映射... 由于Java.util包中的Map数据结构中有一个键... 是否还有其他方法... - AGeek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接