我正在尝试,给定一些整数的ArrayList,创建该列表的所有排列。我想将每个排列(ArrayList本身)存储在ArrayLists的更大的ArrayList中。我可以找到排列并将每个打印到控制台而不会出现问题。我还没有找到一种方法将它们成功添加到列表中。我目前的尝试如下所示。
//myList is a field that I need to use elsewhere
//a is the ArrayList of Integers
//initially, n is a.size()
private static void perm2(ArrayList<ArrayList<Integer>> myList,
ArrayList<Integer> a, int n)
{
for (int i = 0; i < n; i++)
{
swap(a, i, n-1);
perm2(where, a, n-1);
swap(a, i, n-1);
}
if (n == 1)
{
System.out.println(a.toString());
myList.add(a);
return;
}
}
这是给出[0,1,2]的输出:
[1, 2, 0]
[2, 1, 0]
[2, 0, 1]
[0, 2, 1]
[1, 0, 2]
[0, 1, 2]
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
打印代码正在向控制台发送正确的东西,那么为什么不立即添加正确的东西呢?如果这不是一个好的方法,我应该朝哪个方向?最终,这些是从每个订单中的列表中检索数据的索引。
提前致谢。
我应该注意,输入列表可以是任意长度,在合理的计算能力范围内。
编辑:对我的疏忽。这是交换代码:private static void swap(ArrayList<Integer> list, int a, int b)
{
T temp = list.get(a);
list.set(a, list.get(b));
list.set(b, temp);
}
答案 0 :(得分:5)
您始终在列表列表中存储相同的列表。然后你交换它的元素并再次存储它。所以你最终得到了对同一个列表的N个引用。在将列表存储在列表列表中之前,您需要复制列表:
myArray.add(new ArrayList<>(a));
答案 1 :(得分:2)
您尚未向我们展示swap
,但我认为它正在修改列表。然后,列表列表包含对同一基础列表的多个引用,该列表处于最终置换状态。基本上,你已经将一个可变对象放入一个列表然后对它进行了更改,同时期望它处于你第一次将它添加到列表时所处的状态。
解决此问题的一种方法是在添加列表时制作清单的防御性副本:
myArray.add(new ArrayList<Integer>(a));
(另外,您调用变量myArray
并说“将它们添加到数组中”,但myArray
是List
并且您要将内容添加到列表中。我是我第一次阅读你的问题时有点困惑。你不应该把列表称为数组。)
答案 2 :(得分:0)
每次拨打电话时都会添加&#39; myArray上的方法,&#39; a&#39;不复制。 myArray会将引用保持为&#39; a&#39;只要。由于引用始终相同,因此最新状态为&#39; a&#39;元素将被打印。
尝试在myArray.add(a)之后立即打印myArray的内容,看看我的意思。
您需要创建一个新的ArrayList实例以避免此问题