简体   繁体   English

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

[英]Java: best way to find and remove an element from linked list

I've been wondering about this for quite some time and haven't found a good answer to that yet on SO. 我一直想知道这个问题已经有一段时间了,在SO上还没有找到一个好的答案。

What I want to do is to find an element in a linked list and delete it immediately. 我要做的是在链表中找到一个元素并立即将其删除。 If I constructed the linked list on my own, it would be easy, since Ijust traverse the doubly linked list: 如果我自己构建链表,那将很容易,因为我只是遍历双重链表:

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

and when you find eg N3, you change the node.previous and node.next pointers such that: 当找到例如N3时,可以更改node.previous和node.next指针,例如:

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

If the element in in the middle, this would require roughly n/2 steps. 如果元素在中间,则大约需要2个步骤。

Is there a proper approach to do this in java.util.LinkedList<Integer> ? java.util.LinkedList<Integer>是否有适当的方法来执行此操作?

An approach that is insufficient for me is: 对我来说不足的方法是:

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

If the element is the middle element in the list (double linked list, so search from end of the list is theoretically possible if index is known) it would require a maximum of roughly n/2 + n/2 = n steps. 如果该元素是列表中的中间元素(双链接列表,则从理论上讲如果知道索引,则可以从列表末尾进行搜索),它最多需要大约n / 2 + n / 2 = n个步长。 Whereas in the self-made traverse it would only need n/2 steps. 而在自制遍历中,只需要n / 2步。

I know those 2 and other approaches are in O(n), but you know, sometimes that n/2 makes a difference in practice. 我知道这2种方法和其他方法都在O(n)中,但是您知道,有时n / 2在实践中会有所不同。

Thanks for your help. 谢谢你的帮助。

Java 8 will do this for you. Java 8将为您完成此任务。

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

This internally loops through the list, checks for each item x whether it satisfies your condition hasCertainProperty , and removes the item. 这将在列表中内部循环,检查每个项目x是否满足您的条件hasCertainProperty ,然后删除该项目。 I guess you should not be concerned about the performance. 我想您不应该担心性能。 Java will handle it for you. Java将为您处理。

Apart from that, you should use ListIterator which was exactly made for that purpose. 除此之外,您应该使用为此目的而专门制作的ListIterator You obtain it by using LinkedList#listIterator : 您可以使用LinkedList#listIterator获得它:

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

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

Its remove does not need any lookup, since it maintains a pointer to the node while iterating. 它的remove不需要任何查询,因为它在迭代时会维护指向该节点的指针。 So it has hands on the node you want to remove. 因此,它可以在要删除的节点上使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM