Java:从链表中查找和删除元素的最佳方法

时间:2019-05-12 09:19:33

标签: java linked-list doubly-linked-list

我已经想了很久了,在SO上还没有找到一个好的答案。

我想做的是在链表中找到一个元素并立即将其删除。如果我自己构建链表,那将很容易,因为我只是遍历双重链表:

-> N1 <-> N2 <-> N3 <-> N4 <-> N5 <-

,当您找到例如N3,您可以更改node.previous和node.next指针,例如:

-> N1 <-> N2 <-> N4 <-> N5 <-

如果元素位于中间,则大约需要n / 2步。

java.util.LinkedList<Integer>中是否有适当的方法来做到这一点?

一种对我来说不足的方法是:

Integer found = null;
for(Integer elem : list){
    if(hasCertainProperty(elem)){
        found = elem;
    } 
}
if(found != null){
    list.remove(found);
}

如果该元素是列表中的中间元素(双链接列表,则从理论上讲,如果知道索引,则可以从列表末尾进行搜索),它最多需要大约n / 2 + n / 2 = n个步长。而在自制遍历中,只需要n / 2步即可。

我知道这2种方法和其他方法都在O(n)中,但是您知道有时n / 2在实践中会有所不同。

感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

Java 8将为您做到这一点。

list.removeIf(x -> hasCertainProperty(x));

这会在列表中内部循环,检查每个项目x是否满足您的条件hasCertainProperty,然后删除该项目。我想您不应该担心性能。 Java将为您处理。

除此之外,您应该使用专门用于此目的的ListIterator。您可以使用LinkedList#listIterator来获取它:

ListIterator<Integer> listIter = list.listIterator(0);
while (listIter.hasNext()) {
    Integer element = listIter.next();

    if (hasCertainProperty(element)) {
        listIter.remove();
        break;
    }
}

它的remove不需要任何查找,因为它在迭代时保持指向该节点的指针。这样它就可以在要删除的节点上动手了。