二维列表的列表

时间:2011-07-18 08:17:59

标签: java multidimensional-array arraylist

我需要二维列表矩阵,例如ArrayList,我想知道在这种情况下什么是最优选的。它只需要4x4大小。

我应该使用像

这样的东西吗?
    ArrayList[][] foo = new ArrayList[4][4];

    ArrayList<SomeClass>[][] foo = new ArrayList[4][4];

并在for循环或

中初始化具有适当类型的每个元素
    ArrayList<ArrayList<ArrayList<SomeClass>>> foo = ArrayList<ArrayList<ArrayList<SomeClass>>>();

第一种方法会生成警告,例如它应该参数化,如果我添加使用第二种,我会得到未经检查的转换警告。但是,如果我循环遍历元素并初始化它们,即使我仍然收到警告,也应该没有任何问题?最后一种方法不产生任何警告,可能工作正常,但感觉有点混乱。

编辑:我的问题得到了一些很好的答案,即使它有点不清楚。但它基本上是如何制作一个列表。创建一个自定义类来处理行/列,使它变得更容易。

4 个答案:

答案 0 :(得分:5)

修复第一个方法如下:

List [] [] foo = new ArrayList [4] [4];

第二种方法不是你需要的。您正在尝试创建4维数组而不是2维数组4 * 4元素。

此外,我想给你一个提示:永远不要在作业左边使用具体的课程,即ArrayList list = ....使用List list = ...

避免使用过于复杂的数据结构。列表的二维数组太复杂了。创建封装一些功能的自定义类,然后创建类的对象的集合/数组(更好的一维)。

答案 1 :(得分:1)

这是带有显式初始化的2x2矩阵的示例。

List<MyClass>[][] matr = new List<MyClass>[][] {
    new List<MyClass> { new ArrayList<MyClass>(), new ArrayList<MyClass>() },
    new List<MyClass> { new ArrayList<MyClass>(), new ArrayList<MyClass>() }
}

答案 2 :(得分:0)

就像Alex已经说过的那样,拥有2维列表的列表非常复杂,容易出错或以wron方式使用。

由于您的数组应该表示一个表,您可能希望为行或列创建类,具体取决于更重要的内容。

或者,您可以为表格中的每个单元格创建一个类,并管理2D单元格数组,如果您确切知道自己拥有的单元格数量:

class Cell {
  private List<SomeClass> content = new ArrayList<SomeClass>();
  ...
}

Cell[][] matrix = new Cell[4][4];  //don't forget to initialize each cell

答案 3 :(得分:0)

    public static class Grid<T> {

    public interface TFactory<T> {

        T create();
    }
    private T[] data;
    private int d1;
    private int d2;

    public Grid(int d1,
            int d2,
            Class<T> clazz,
            TFactory<T> fac) {
        this.d1 = d1;
        this.d2 = d2;
        data = (T[]) Array.newInstance(clazz, d1 * d2);
        for (int i = 0; i < data.length; i++) {
            data[i] = fac.create();
        }
    }

    public T get(int c1,
            int c2) {
        return data[c1 * d2 + c2];
    }
}

public static class ArrayListFactory<X> implements Grid.TFactory<ArrayList<X>> {

    public ArrayList<X> create() {
        return new ArrayList();
    }
}

public static void main(String[] args) throws RTXException, ParseException {
    // cannot use new new ArrayList<String>[4][4];, because of generic array creation error
    List<String>[][] a2d = new ArrayList[4][4];
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            a2d[i][j] = new ArrayList<String>();
        }
    }
    Grid g = new Grid(4, 4, ArrayList.class, new ArrayListFactory<String>());
}

这是两种方法。首先是你要求的,第二个是封装版本(将2d数组转换为1d数组以便于内部操作)。

如前所述,您应该尽可能多地将变量声明为接口(但不能更多)。 这意味着,如果您只想说,它是一个List,并且不希望任何人根据具体实现表现出不同的行为,只需使用List,而不是ArrayList作为变量类型。 但如果你使用eg。 LinkedSet最好使用LinkedSet作为变量类型(以及作为函数的返回值),如果你想“保证”它按顺序和插入顺序列出所有元素。如果使用Set,则其用户不应该依赖于任何特定的迭代顺序。

顺便说一句。注意显式初始化。这是很好的语法,但它创建了匿名内部类,它可以导致父类的意外保留。但是如果你知道自己在做什么并且不可能发生(没有外部参考),那么使用它并没有错。