如何在Java中允许一个对象从LinkedList中移除自己



主要问题:我正在寻找某种方法来给LinkedList中的对象一个对列表中自身的引用,以便它可以(有效地)从所述列表中删除自己(而不需要对列表进行排序寻找自己)。我想让它直接从列表中删除自己,并将前一项和下一项绑定在一起。

Less Necessary Details:我在谷歌上搜索了相当多,除了有人建议不要使用循环引用之外,什么也没找到。

我想这样做,因为我正在设计一款游戏,在游戏中,对象可以执行各种接口,使它们能够以优先顺序循环通过各种列表。单个对象可能同时处于绘制循环、动画帧步进循环、高优先级逻辑循环和低优先级逻辑循环中。我想在每个适当的接口中实现removeFrom|TypeOfLoop|方法,这样如果一个对象决定它不再需要在循环中,它可以直接删除自己。这使得执行实际循环的对象非常简单。

或者,如果没有办法做到这一点,我正在考虑实现一个标记系统,其中列表检查,看看每个项目是否希望基于项目内的变量被删除。然而,我不喜欢这样做的想法,可能只是做我自己的LinkedList,能够通过引用删除。

我最近就这么做了。我正在寻找一个O(1)添加O(1)删除无锁的Collection。最后,我编写了自己的Ring,因为我想要一个固定大小的容器,但是您可以找到我在第一次尝试中使用的技术。

我前面没有代码但是如果我没记错的话:

以Doug Lea的优秀并发双重LinkedList为例:

  1. 暴露Node类。我用的是interface,但这取决于你。

  2. 更改add, offer…方法返回Node而不是boolean它现在不再是java Collection,但请稍后查看我的评论。

  3. 暴露Node类的delete方法或添加一个remove方法,该方法接受一个Node

现在可以在0(1)时间内从列表中删除元素,并且它是Lock Free

添加

这是remove(Node)方法的实现,取自他的Iterator实现。请注意,你必须不断尝试,直到你成功。

public void remove(Node<E> n) {
  while (!n.delete() && !n.isDeleted())
    ;
}

我认为你的替代方案比让项目从循环中删除要好得多。它减少了列表中对象的责任,并避免了循环引用。

此外,您可以使用Guava的Iterables.filter()方法并遍历过滤列表,而不是在每次迭代时显式检查对象是否应该呈现。

即使你想做的事情是可能的,当你从列表中删除一个对象时,你会得到一个ConcurrentModificationException,同时迭代它。要做到这一点,唯一的方法是从迭代器中删除当前对象。

如果你正在使用LinkedList,没有比迭代它并在找到元素时执行iterator.remove()更有效的删除项的方法了。

如果你正在使用google collection或guava,你可以在一个online line中做:

Iterables.removeIf(list.iterator(), Predicates.equalTo(this));

最简单的方法是修改算法,使用Iterator遍历List对象,并使用Iterator.remove()方法删除当前元素。

相关内容

  • 没有找到相关文章

最新更新