【发布时间】:2010-06-23 14:55:45
【问题描述】:
我是 Java 新手,我需要制作一个列表列表。我可以在 python 中执行此操作,因为列表的元素可以是列表,因此在嵌入式列表中list[0] 将引用一个列表,list[0][0] 将引用嵌入列表的第零个元素。有什么简单的方法可以在 java 中实现这种行为吗?
【问题讨论】:
我是 Java 新手,我需要制作一个列表列表。我可以在 python 中执行此操作,因为列表的元素可以是列表,因此在嵌入式列表中list[0] 将引用一个列表,list[0][0] 将引用嵌入列表的第零个元素。有什么简单的方法可以在 java 中实现这种行为吗?
【问题讨论】:
所有其他答案在技术上都是正确的,但是恕我直言,如果您实现了一个粗略的 List of Lists 列表,那么您就没有在正确的抽象级别上处理您的数据。例如,我很确定 List of Lists 在您的业务领域中已经意味着“某事”。将这个“东西”封装在另一个对象中,这样您就可以只拥有一个 List>>。
【讨论】:
正如Mario 所说,您可能需要进一步抽象出您的数据。但是,以下将满足您的需要。
在 Java 中你会这样:
List<List<List<Object>>> listOfListsOfLists =new ArrayList<List<List<Object>>>();
然后要访问这些项目,您将使用:
listOfListsOfLists.get(a).get(b).get(c);
或者,遍历所有内容:
for (List<List<Object>> list2: listOfListsOfLists) {
for (List<Object> list1: list2) {
for (Object o: list1) {
// use `o`
}
}
}
【讨论】:
由于所有这些答案都让我感到恶心,我可以添加您的建议
创建一个数据类型来表达你的数据,同时封装结构的细节,或者至少
创建一个包装 int[] 的键类型(但正确覆盖 equals 和 hashCode)并使用 HashMap 代替?无论如何,您的整个 3 维结构通常很少会被填满。
更好的是,您可以封装该映射并使用可变参数进行干净访问。
public class NDimensionalArray<V> {
private final int dimensions;
private final Map<Key, V> values = new HashMap<Key, V>();
private NDimensionalArray(int dimensions) {
this.dimensions = dimensions;
}
public V get(int... indices) {
checkIndices(indices);
return values.get(new Key(indices));
}
public void set(V value, int... indices) {
checkIndices(indices);
values.put(new Key(indices), value);
}
private void checkIndices(int[] indices) {
if ( indices.length != dimensions ) {
throw new IllegalArgumentException();
}
}
private static final class Key {
private final int[] indices;
private Key(int[] indices) {
this.indices = indices;
}
@Override
public int hashCode() {
return Arrays.hashCode(indices);
}
@Override
public boolean equals(Object obj) {
return Arrays.equals(indices, ((Key)obj).indices);
}
}
}
如果人们有已经建立的收藏库的例子,已经做这种事情,请告诉我,我会添加链接。
【讨论】:
虽然您可以在 Java 中构造 List>> 确实是真的,但我不禁想知道,您为什么要这样做?并不是说这是解决您的问题的最佳方法是不可思议的,但是哇,为什么?
我想我可以想象类似的东西
public class Employee ...
List<Employee> store; // all the employees in a store
List<List<Employee>> city; // all the store lists for a city
List<List<List<Employee>>> nation; // all the store lists for the nation
但是你真的想这样处理吗?我不知道,这取决于你需要用它做什么。
【讨论】:
一个全面的例子展示了 List-of-List 与集合和泛型 (Java 1.5+)
// declare the list of lists
List<List<String>> listOfListOfStrings = new ArrayList<List<String>>();
// populate
List<String> listOfStrings = new ArrayList<String>(); // one inner list
listOfStrings.add("one-one");
listOfStrings.add("one-two");
listOfListOfStrings.add(listOfStrings);
listOfStrings = new ArrayList<String>(); // and another one
listOfStrings.add("two-one");
listOfStrings.add("two-two");
listOfListOfStrings.add(listOfStrings);
// access
String oneOne = listOfListOfStrings.get(0).get(0); // first element of first inner list
String twoTwo = listOfListOfStrings.get(1).get(1); // second element of second inner list
【讨论】:
add 是包listOfStrings 中的一个类(这显然是错误的)。 listOfStrings 是一个局部变量,声明就在 //populate 注释的正下方。验证您的导入语句并仔细检查代码是否在方法内。 (你有一个名为add 的类吗?)