我已经想了很久了,在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在实践中会有所不同。
感谢您的帮助。
答案 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
不需要任何查找,因为它在迭代时保持指向该节点的指针。这样它就可以在要删除的节点上动手了。