主要问题:我正在寻找某种方法来给LinkedList中的对象一个对列表中自身的引用,以便它可以(有效地)从所述列表中删除自己(而不需要对列表进行排序寻找自己)。我想让它直接从列表中删除自己,并将前一项和下一项绑定在一起。
Less Necessary Details:我在谷歌上搜索了相当多,除了有人建议不要使用循环引用之外,什么也没找到。
我想这样做,因为我正在设计一款游戏,在游戏中,对象可以执行各种接口,使它们能够以优先顺序循环通过各种列表。单个对象可能同时处于绘制循环、动画帧步进循环、高优先级逻辑循环和低优先级逻辑循环中。我想在每个适当的接口中实现removeFrom|TypeOfLoop|方法,这样如果一个对象决定它不再需要在循环中,它可以直接删除自己。这使得执行实际循环的对象非常简单。
或者,如果没有办法做到这一点,我正在考虑实现一个标记系统,其中列表检查,看看每个项目是否希望基于项目内的变量被删除。然而,我不喜欢这样做的想法,可能只是做我自己的LinkedList,能够通过引用删除。
我最近就这么做了。我正在寻找一个O(1)添加O(1)删除无锁的Collection
。最后,我编写了自己的Ring
,因为我想要一个固定大小的容器,但是您可以找到我在第一次尝试中使用的技术。
我前面没有代码但是如果我没记错的话:
以Doug Lea的优秀并发双重LinkedList为例:
-
暴露
Node
类。我用的是interface
,但这取决于你。 -
更改
add
,offer
…方法返回Node
而不是boolean
。它现在不再是javaCollection
,但请稍后查看我的评论。
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()方法删除当前元素。