2016-07-23 80 views
1

我有一个对象的集合,我需要一个迭代器,它可以按顺序(向前和向后)遍历对象,但也可以在给定该对象的索引时转到任何对象代表任务的课程编号)。非顺序索引集合

但是,每个对象的索引都需要按顺序进行特别的预定义,并且不能保证我的对象列表将具有顺序索引(例如,我可以使用索引0,1,6,9) 。我目前有一个ArrayList(),我正在用最大的索引实例化,我期望可以作为初始容量,但是当我尝试在我的ArrayList上使用add(index,Object)方法时,我不断收到ArrayIndexOutOfBounds异常

我的代码看起来是这样的:

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); 
    } 

和控制台吐出这样的事情(窗口cmdpromt不支持复制/粘贴> _ <):

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 ...) 

我不为什么大小== 0当我创建应该是一个大小为4的ArrayList?

一个相关的问题:当我有一个更好的默认Java集合用于这种情况时,我滥用ArrayList(和它的ListIterator)吗?期望的最终结果是我的对象有一个迭代器对象,它能够来回遍历并到达特定位置(现在,如果存在,我将在给定索引处创建新的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 
    )); 
+0

太棒了,谢谢!我最终需要的是一个NavigableMap,然后是一个游标Integer值来跟踪我的位置,它的运行效果很好。谢谢您的帮助! – CrypticCabub