Java中使用ArrayList实现二维动态数组

4

我需要实现一个二维动态数组。行数是固定的,比如说n。但是每一行的列数不固定且不相等。例如,第一行有3个元素,第二行有5个元素。如何使用ArrayList在Java中实现这个功能。谢谢。


在你的例子中,第一行始终有3个元素吗?如果是这样,为什么不直接创建一个(例如)Something [] [] s = new Something [numRows] []s [0] = new Something [3]呢? - Tedil
9个回答

3

关于List<List<Foo>>怎么样?

例如:

List<List<Foo>> list = new ArrayList<List<Foo>>();

List<Foo> row1 = new ArrayList<Foo>();
row1.add(new Foo());
row1.add(new Foo());
row1.add(new Foo());
list.add(row1);

List<Foo> row2 = new ArrayList<Foo>();
row2.add(new Foo());
row2.add(new Foo());

list.add(row2);

什么是列表和ArrayList之间的区别?为什么只有 ArrayList<ArrayList<Foo>> list = new ArrayList<ArrayList<Foo>>();? - user288609
3
List是一个接口,ArrayList是它的具体实现。如果你有List<Foo>,那么你也可以引用LinkedList或其他实现方式。 - jmj

2
ArrayList<ArrayList<SomeObject>> twodlist = new ArrayList<ArrayList<SomeObject>>();
ArrayList<SomeObject> row = new ArrayList<SomeObject>();
row.add(new SomeObject(/* whatever */));
// etc
twodlist.add(row);
row = new ArrayList<SomeObject>();
// etc

2
几乎可以,除了2dlist不是Java的有效标识符。 :) - Ted Hopp
@Ted Hopp,你在哪里看到那个标识符?;-) 感谢您的纠正 :-) - MarioP

2
您可以使用数组来表示行,因为这个维度是固定的:
@SuppressWarnings("unchecked")
ArrayList<T>[] arr = new ArrayList[ fixedsize];

或者使用嵌套的ArrayList:

List<List<T>> list = new ArrayList<List<T>>( fixedsize );

Java编译器禁止创建泛型数组。 - MarioP
不,这并不是被禁止的!你完全可以创建参数化类型的数组,并且你可以测试我的代码。它编译并按预期工作。 - x4u
抱歉,你是对的,我的代码有错误,强制转换可以省略。我已经修复了它,现在可以编译了。 - x4u
啊哈,没错,就是这个。之前没注意到。如果实际变量不是原始类型,我可以假设它是类型安全的吗? - MarioP
它实际上比通用集合类型更安全,因为它保证数组中永远不会有一个不是数组组件类型实例的对象。所以你可以百分之百确定该数组始终包含ArrayList对象(或null),但永远不会是字符串等其他对象。一个 ArrayList<ArrayList<T>> 在技术上可以容纳任何你喜欢的对象,虽然你需要使用一些难看的转换或反射才能做到这一点。除此之外,数组和集合类型的类型安全性或缺乏类型安全性是相同的。 - x4u

1

尝试:

ArrayList<ArrayList<DataType>> array = new ArrayList<ArrayList<DataType>>();
for (int i = 0; i < n; ++i) {
    array.add(new ArrayList<DataType>());
}

1
你不能混合使用数组和泛型。 - trutheality
更正:你可以使用@SuppressWarnings("unchecked"),但是不建议这样做。 - trutheality
但是如何为每个表示行的ArrayList添加条目呢?谢谢。 - user288609
@MarioP:你是什么意思?此外,查看此答案以获取完整的解释。 - trutheality
@MarioP 必须在 new 语句中不使用 <SomeObject> 来完成。像这样:http://ideone.com/A7fpO - trutheality
显示剩余3条评论

0
我会创建一个ArrayList数组(如果行数为3,则ArrayList [3] rows = new ArrayList [3])。然后,为每一行创建列类并将它们插入到ArrayList中,然后将ArrayList放入数组中。行数组的索引可用于跟踪行号。请记住,数组从0开始索引,因此行号将是rows [index + 1]。

0
正如你所说,你可以创建一个数组的ArrayList,并使用ArrayList(int initial capacity)构造函数设置每列的容量:
ArrayList<YourObject>[] rows=new ArrayList<YourObjects>[n];
for(i=0;i<n;i++){
rows[i]=ArrayList<YourObjects>(initialsize);
}

1
ArrayList 是一个原始类型。对泛型类型 ArrayList<E> 的引用应该进行参数化 - 这是一种糟糕的编码风格,会带来 ClassCastException 高风险。 - MarioP
好的发现 - 感谢您的更正!上面的代码已经修复。 - CodeRedd
显然,我需要好好复习一下ArrayList。^^ - CodeRedd

0
你可以创建一个 ArrayList 元素的数组,因为你的行数是固定的。
ArrayList[] dynamicArray = new ArrayList[n]();

注意:您需要在数组的每个条目中分配一个ArrayList对象。因此...
for (int loop = 0; loop < n; loop++)
dynamicArray[loop] = new ArrayList();

如果您希望行和列都是动态的,您可以创建一个ArrayList的ArrayList....

ArrayList<ArrayList<T>> dynamicArray = new ArrayList<ArrayList<T>>();

再一次,您需要在dynamicArray的每个新条目中创建一个数组列表。


0
如果行数已固定,可以尝试类似以下方式:
ArrayList<MyObject>[] = new ArrayList<MyObject>[fixedRows]

Java编译器禁止创建泛型数组。 - MarioP
需要使用@SuppressWarnings("unchecked")来确保它始终起作用。 - trutheality
该死的Java泛型...然后 ArrayList[] = new ArrayList[fixedRows]。讨厌你Java。 - erickzetta
@erikzetta:确实很烦人,我已经放弃了,在处理这样的情况时转向使用全泛型--反正开销非常小。 - trutheality

0
List<ArrayList<SomeObject>> twoDList = new ArrayList<List<SomeObject>>(n);
for( int i=0; i<n; i++ )
    twoDList.add( new ArrayList<SomeObject>() );

使用方式:

twoDList.get(rownumber).add(newElementInColumn);

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