简体   繁体   English

给定指针,从LinkedList集合中删除一个元素

[英]Given the pointer, deleting an element from a LinkedList collection

I have a LinkedList of objects, and a pointer to an object of the LinkedList which I want to delete. 我有一个对象的LinkedList ,以及一个指向要删除的LinkedList对象的指针。

There is a method remove(object o) , which can be used to do delete an object, but as the documentation describes, it checks for all the elements one by one, and chooses the one object, which is the same semantically. 有一个方法remove(object o) ,可以用来删除一个对象,但是正如文档所描述的,它一步一步地检查所有元素,并选择一个在语义上相同的对象。

But this method doesn't fit my requirements. 但是这种方法不符合我的要求。

Since I have a pointer to the object I want to delete, I should be able to delete it in O(1) time, since the LinkedList is a doubly linked list. 因为我有一个指向要删除的对象的指针,所以我应该能够在O(1)时间内删除它,因为LinkedList是一个双向链接列表。 Is there any other way to do so without implementing my own LinkedList class? 还有其他方法可以实现我自己的LinkedList类吗?

You cannot delete an object from a LinkedList in O(1) if all you have is a reference to the object itself. 如果您仅拥有对对象本身的引用,则无法从O(1)的LinkedList中删除对象。

You can delete an object if you keep a ListIterator<E> object positioned at the item that you would like to remove by calling remove() on the iterator, but it does not help much, because your iterator would get invalidated the moment the list is modified. 如果将ListIterator<E>对象保持在要删除的项目上,则可以删除该对象,方法是在迭代器上调用remove() ,但这没有多大用处,因为在列表出现时迭代器将失效被修改。

Here is an example of how to keep the removal O(1). 这是一个如何保持去除量O(1)的示例。 Search remains O(n), though: 搜索仍然为O(n),但:

List<String> list = new LinkedList<>();
list.add("hello");
list.add("world");
list.add("one");
list.add("two");
list.add("three");
System.out.println(Arrays.toString(list.toArray()));
ListIterator<String> iter = list.listIterator();
String s;
while ((s = iter.next()) != null && !s.equals("world"))
    ;
// When it is time to delete
iter.remove();
System.out.println(Arrays.toString(list.toArray()));

Because of the ConcurrentModificationException , writing your own implementation of LinkedList<E> and keeping a reference to the node for future deletion remains your best option with pure linked lists. 由于ConcurrentModificationException ,编写纯链接列表的最佳选择是编写自己的LinkedList<E>并保留对节点的引用以供将来删除。

Your other option is using LinkedHashSet<E> , which offers predictable enumeration order and O(1) deletions in exchange for using more memory. 您的另一个选择是使用LinkedHashSet<E> ,它提供可预测的枚举顺序和O(1)删除,以换取更多的内存。

How about: 怎么样:

public void remove(Car searchedFor) {
  for (Iterator<Car> it = list.iterator(); it.hasNext(); ) {
    Car c = it.next;
      if (c == searchedFor) {
        it.remove();
      }
    }
  }

A good solution to my problem was using both List and HashSet together. 一个很好的解决方案是同时使用ListHashSet Since we're using a HashSet we can't work with duplicates. 由于我们使用的是HashSet ,因此无法使用重复项。

Insertion: Insert in both List and HashSet . 插入:同时插入ListHashSet O(1) time. O(1)时间。
Deletion: Delete from HashSet , if exists. 删除:HashSet删除(如果存在)。 O(1) time. O(1)时间。
Traversal: Traverse the List . 遍历:遍历List Access only if the HashSet contains that object. 仅在HashSet包含该对象时访问。

Note that I'm not trying to replicate the working of a LinkedList here. 请注意,我不是在这里尝试复制LinkedList的工作。 I'm just sharing what worked for me. 我只是分享对我有用的东西。

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

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