我想通过遍历ArrayList
并将每个元素复制到新列表中的特定位置来重新排列它。
在这种情况下,我想将一个元素移动到列表的末尾。例如,如果列表是ABCDE和j == B,那么新列表应该是ACDEB。
这是我的代码:
private ArrayList<Job> schedule;
private ArrayList<Job> tempSchedule;
...
schedule = input;
tempSchedule = new ArrayList<Job>(schedule.size());
...
private void moveJob(int j) {
for(int i = 0; i < schedule.size(); i++) {
if(i == j) { //move to the end
tempSchedule.set(schedule.size()-1, schedule.get(i));
} else {
if(i > j && i <= schedule.size() -1) { //move one position back
tempSchedule.set(i - 1, schedule.get(i));
} else { //same position
tempSchedule.set(i, schedule.get(i));
}
}
}
schedule = tempSchedule;
u++;
}
现在我在tempSchedule.set上得到了一个IndexOutOfBoundsException: Index: 0, Size: 0
我想问题出在这条线上
tempSchedule = new ArrayList<Job>(schedule.size());
另外,请解释如何制作深度复制。
编辑:感谢您的所有答案。我通过简单地删除该项目并将其添加到最后来运行它,就像建议的那样。
我想构建一个新列表的原因是因为我可能不得不在某个时候进行更复杂的重新排列。
首先,去阅读 ArrayList 和集合上的 javadoc。
新的 ArrayList(capacity) 不会复制,它只是分配一个具有该容量的列表。 要复制列表(它不是克隆,它是一个参考副本,再次你需要回到基础)将是新的 ArrayList(oldArrayList)。
其次,您的测试大小为 0,因此其中没有对象,因此 get(0)(正确且符合规范)会抛出索引越界异常,因为您的列表为空。
除此之外,set和get都不会修改列表,因此,如果您正确创建了副本并且其内容是ABCD并且您执行了该操作,则其内容将是ABCB。 你想要的是。
X = tempSchedule.remove(i) // removes element at I
tempSchedule.add(X) // adds element to end of list
tempSchedule
初始化为空:
tempSchedule = new ArrayList<Job>(schedule.size());
您不能在空ArrayList
上使用set
。它期望要替换的索引已经具有值。
当i==0
时,您会在此行中得到异常 - tempSchedule.set(i, schedule.get(i));
-
set
呼叫RangeCheck
:
/**
* Checks if the given index is in range. If not, throws an appropriate
* runtime exception. This method does *not* check if the index is
* negative: It is always used immediately prior to an array access,
* which throws an ArrayIndexOutOfBoundsException if index is negative.
*/
private void RangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
}
如您所见,传递给它的索引必须小于列表的当前大小。
问题是您的tempSchedule
列表是空的。 set()
覆盖给定位置的元素。如果您的列表为空,则无法执行此操作。
这可能有点令人困惑,因为您写了new ArrayList<Job>(schedule.size())
.但是您传递的参数不会设置大小,而是设置初始容量,这意味着底层数组的初始大小,可以在必须调整大小之前使用它。
原因是当您使用调度大小定义 arrayList 时,它是一个空列表,即不包含任何内容。
因此,当您尝试设置元素(用于替换现有元素)时,它会将索引与列表的大小进行比较,并发现索引为 0,大小也是 0。
请注意,仅通过将 size 作为构造函数传递,您不会更改 arrayList 的大小。因此,为了避免这种情况,您需要使用:
tempSchedule = new ArrayList<Integer>(schedule);
而不是
tempSchedule = new ArrayList<Integer>(schedule.size());
你有IndexOutOfBoundsException
,因为你在 for 循环中使用schedule.size
,而它null
你必须使用 tempSchedule.size
代替。
而且您正在比较i and j
,而您必须比较tempSchedule.get(i) and j
.
你有一个语法谬误,就像其他答案所说的那样。
我更关心你的方法。
你不能简单地做:
private void moveJob(int j) {
Job toMove = tempSchedule.get(j);
tempSchedule.remove(j);
tempSchedule.add(toMove);
}
或者更简洁:
private void moveJob(int j) {
tempSchedule.add(tempSchedule.remove(j));
}