非连续索引集合

时间:2016-07-23 18:53:55

标签: java arraylist collections

我有一个对象的集合,我需要一个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,如果它存在的话)

1 个答案:

答案 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
    ));