Java:有没有办法有效地插入或删除LinkedList中间的许多元素?

时间:2012-10-21 22:37:27

标签: java data-structures linked-list

我期待在Java的LinkedList中找到它,因为链接列表的要点是能够有效地插入(和删除)任何地方(假设您有某种指向要插入或删除的位置的指针) 。我虽然没有在API中找到任何东西。我忽略了什么吗?

我能找到的最接近的是ListIterator中的add和remove方法。但这有一些局限性。特别是,根据API,一旦通过remove修改了底层LinkedList,其他迭代器就会变为无效。这也是在我的测试中诞生的;以下程序导致IllegalStateException:

import java.util.*;
public class RemoveFromLinkedList {
    public static void main(String[] args) {
        LinkedList<Integer> myList= new LinkedList<Integer>();
        for (int i = 0; i < 10; ++i) {
            myList.add(i);
        }

        ListIterator<Integer> i1 = myList.listIterator();
        ListIterator<Integer> i2 = myList.listIterator();
        for (int i = 0; i < 3; ++i) {
            i1.next();
            i2.next();
        }

        System.out.println("i1.next() should be 3: " + i1.next());
        i1.remove();
        i1.remove();

        // Exception!
        System.out.println("i2.next() should be 5: " + i2.next());
    }
}

理想情况下,我期待的是这样的:

// In my imagination only. This is the way Java actually works, afaict.

// Construct two insertion/deletion points in LinkedList myLinkedList.
myIterator = myLinkedList.iterator();
for (...) {
 myIterator.next();
}
start = myIterator.clone();
for (...) {
 myIterator.next();
}

// Later...

after = myLinkedList.spliceAfter(myIterator, someOtherLinkedList);
// start, myIterator, and after are still all valid; thus, I can do this:
// Removes everything I just spliced in, as well as some other stuff before that.
myLinkedList.remove(start, after);
// Now, myIterator is invalid, but not start, nor after.

C ++的list类(模板)就是这样的。只有指向移动元素的迭代器才会失效,而不是所有迭代器。

3 个答案:

答案 0 :(得分:2)

如果使用迭代器删除某些东西,你仍然可以继续使用相同的迭代器。可以这样做

iterator.remove();
iterator.next();
iterator.remove();
iterator.next();

据我所知,这是最接近的事情。

答案 1 :(得分:2)

你可以用List.subList(startIndex, endIndex)做有趣的事情。使用此功能,您可以清除“源”列表中的整个范围。您还可以在子列表中使用addAll将新内容插入到源列表中。

如果LinkedList有一个有效的实现 - 我不知道。

答案 2 :(得分:1)

使用java.util.LinkedList,引用列表中的位置以便以后进行有效操作的唯一方法是迭代器,如果基础列表被此迭代器以外的其他东西修改,则迭代器将失效。

如果你真的需要这种功能,你必须超越Java API,或者自己编写。