(Java)使用for循环获取所有组合并添加到ArrayList,但ArrayList只有最后一个添加
我在编写java程序时遇到了一个问题。我想在一个字符串数组中生成元素的所有可能组合,并将每个可能的组合存储到一个完整的ArrayList中 我使用for循环遍历所有可能的组合,并使用ArrayList.add添加每个字符串数组。但是,当我试图打印要检查的ArrayList时,它在所有位置都只有最后一个字符串数组 如果我将(Java)使用for循环获取所有组合并添加到ArrayList,但ArrayList只有最后一个添加,java,arrays,for-loop,arraylist,Java,Arrays,For Loop,Arraylist,我在编写java程序时遇到了一个问题。我想在一个字符串数组中生成元素的所有可能组合,并将每个可能的组合存储到一个完整的ArrayList中 我使用for循环遍历所有可能的组合,并使用ArrayList.add添加每个字符串数组。但是,当我试图打印要检查的ArrayList时,它在所有位置都只有最后一个字符串数组 如果我将System.out.println移动到for循环的内部,一切看起来都很好。如果我将打印移动到循环的外部,它只会显示我在所有位置都只有相同的字符串数组 与代码的两部分相关的问题
System.out.println
移动到for循环的内部,一切看起来都很好。如果我将打印移动到循环的外部,它只会显示我在所有位置都只有相同的字符串数组
与代码的两部分相关的问题:
String[] inputs = {"1", "2", "3", "4", "5", "6"};
int maxLength = 4;
//Get the total number of all combinations with replacement, used for the for loop
int total = (int) Math.pow(inputs.length, maxLength);
ArrayList<String[]> allList = new ArrayList<>();
System.out.println(total);
String[] subSets = new String[maxLength];
int [] index = new int [maxLength];
Arrays.fill(index, 0);
for (int i = 0; i < total; i++)
{
for (int j = 0; j < maxLength; j++)
{
subSets[j] = inputs[index[j]];
}
allList.add(i, subSets);
if (i != (total - 1))
index = nextIndex (index, maxLength, inputs.length);
// Set the print here everything looks fine
System.out.println(Arrays.toString(allList.get(i)));
}
// However, if you pit it here to check if you get the correct ArrayList, problem happens
//for (int g = 0; g < total; g++)
//System.out.println(Arrays.toString(allList.get(g)));
我的程序的这一部分的思想是从字符串数组“inputs”生成所有可能的组合(带有替换),并将这些组合存储到一个完整的ArrayList中。打印出来只是我的习惯,检查每一步是否正确
我不断得到的错误输出(只是输出的一部分):
我希望获得的正确输出:
[1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 1, 3]
[1, 1, 1, 4]
[1, 1, 1, 5]
[1, 1, 1, 6]
您正在for循环外部创建子集数组,因此始终更新同一数组。这就是为什么在最后你会得到最后一个排列。 将“字符串[]子集=新字符串[maxLength];”移动到与“i”相关的for循环中
对于(int i=0;i
您将获得正确的输出:
1296
[1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 1, 3]
[1, 1, 1, 4]
[1, 1, 1, 5]
.....
[6, 6, 6, 4]
[6, 6, 6, 5]
[6, 6, 6, 6]
您正在为循环创建子集
数组,因此列表中的所有内容都指向上次更新的子集
对象,即[6,6,6,6]
。您一次又一次地将同一对象添加到列表中,因此它将更新列表中所有位置的最新值
将其移动到for
循环中,如下所示:
for (int i = 0; i < total; i++)
{
/* Move It Here */
String[] subSets = new String[maxLength];
for (int j = 0; j < maxLength; j++)
{
subSets[j] = inputs[index[j]];
}
allList.add(subSets);
if (i != (total - 1))
index = nextIndex (index, maxLength, inputs.length);
}
for(int i=0;i
是学习使用调试器逐步执行的时候了。非常感谢您的评论。这确实对我有用。然而,我仍然不明白,如果我在循环之外创建它,为什么它不起作用?你能再解释一下吗?因为我认为在嵌套的for循环中,数组将被更新。还有一个问题,最后一个排列如何能够接管ArrayList中的所有其他位置?谢谢@丁先生,因为如果你在循环之外创建它,那么你就在一次又一次地将同一个对象添加到你的列表中。它指向相同的系统内存位置,因此,如果该值被更新,那么它将反映到所有位置。最后一个被更新的值是[6,6,6,6]
,当这个值在内存中更新时,它会反映在整个列表中,因为所有列表项都包含相同的对象。哦,我明白了。非常感谢你!感谢@user2004685扩展我的简短解释。非常感谢您的评论。它起作用了。我认为在嵌套for循环中,数组将被更新。我真的不明白最后一个排列怎么能取代ArrayList中的所有其他位置?你是说java知道我正在添加相同的对象,所以它会更新所有对象吗?谢谢@丁先生:是的。JAVA知道!:)正如我上面所说的,如果您在循环之外创建对象,那么您将一次又一次地将相同的对象(相同的引用)添加到列表中。它指向相同的系统内存位置,因此,如果对象值被更新,那么它将反映到所有位置。正在更新的最后一个值是[6,6,6,6]
,当该值在内存中更新时,它会反映在整个列表中,因为所有列表项都包含相同的对象。
[1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 1, 3]
[1, 1, 1, 4]
[1, 1, 1, 5]
[1, 1, 1, 6]
for (int i = 0; i < total; i++)
{
/* Move It Here */
String[] subSets = new String[maxLength];
for (int j = 0; j < maxLength; j++)
{
subSets[j] = inputs[index[j]];
}
allList.add(subSets);
if (i != (total - 1))
index = nextIndex (index, maxLength, inputs.length);
}