我有一个对象的集合,我需要一个Iterator,它可以按顺序遍历对象(向前和向后),但在给定该对象的索引时也可以转到任何对象(它代表的是作业)。
但是,每个Object的索引需要按顺序专门预定义,并且不能保证我的对象列表将具有顺序索引(例如,我可以使用索引0,1,6,9)。
我目前有一个ArrayList()我用bigIndex实例化我希望可以作为初始容量,但每当我尝试在我的ArrayList上使用add(index,Object)方法时,我一直得到ArrayIndexOutOfBounds异常< / p>
我的代码如下:
int largestIndex = unindexedAssignments.get(unindexedAssignments.size() - 1).getAssignmentID();
//index of 0 is ignored so add +1 to make sure we have enough space
assignments = new ArrayList<>(largestIndex + 1);
System.out.println("LargestIndex: " + (largestIndex + 1));
//populate assignments List
for(Assignment assignment : unindexedAssignments) {
//add the assignment to the list such that the index == the lesson number
System.out.println("adding assignment with index of " + assignment.getAssignmentID());
assignments.add(assignment.getAssignmentID(), assignment);
}
并且控制台吐出这样的东西(windows cmdpromt不支持复制/粘贴&gt; _&lt;):
largestIndex: 3
adding assignment with index of 1
java.lang.IndexOutOfBoundsException: Index 1, Size: 0
at java.util.ArrayList.rangeCheckForAdd(Unkown Source)
at java.util.ArrayList.add(Unknown Source)
(the rest of the stack trace pointing to the section of code I gave above ...)
当我创建应该是大小为4的ArrayList时,我不知道为什么Size == 0?
一个相关的问题:当有一个更好的默认Java集合用于这种情况时,我是否滥用了ArrayList(以及它的ListIterator)?期望的最终结果是我的对象有一个Iterator对象,它能够来回遍历并转到一个特定的位置(现在我只想在给定的索引处创建一个新的ListIterator,如果它存在的话)
答案 0 :(得分:2)
List
s不支持稀疏索引。如果要添加到列表末尾的索引,则还必须创建所有中间索引。
使用SortedMap
。当您拥有非连续索引时,地图非常适合。您可以按其课程编号查找任何作业,并且可以按顺序迭代所有键值对。
SortedMap<Integer, Assignment> assignments = new TreeMap<>();
for (Assignment assignment: unindexedAssignments) {
assignments.put(assignment.getAssignmentID(), assignment);
}
您还可以使用Java 8流式语法替代显式循环。
Map<Integer, Assignment> assignments = unindexedAssignments.stream()
.collect(Collectors.toMap(
a -> a.getAssignmentID(), // keys
a -> a, // values
(a, b) -> throw new IllegalStateException("duplicate lesson number"),
// what to do if two items have the same key
TreeMap::new // map class constructor
));