Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ConcurrentSkipListSet和重新排序(java)_Java_List_Sorting_Concurrency - Fatal编程技术网

ConcurrentSkipListSet和重新排序(java)

ConcurrentSkipListSet和重新排序(java),java,list,sorting,concurrency,Java,List,Sorting,Concurrency,我使用的是ConcurrentSkipListSet,它显然是通过多个线程访问的。现在,基础对象的compareTo方法使用的值会随着时间的推移而改变。因此,我想“更新”列表的顺序(通过使用它或类似的方法) 但是,java.util.Collections.sort(list)不起作用,仅仅重建列表可能太慢(并且会破坏整个并发性证明)。有没有其他的解决方案我应该考虑 它不必导致最佳排序(对于并发性和不断变化的值来说,这几乎是不可能的)。只要任何remove/add调用保持线程无关(在排序时重建列

我使用的是ConcurrentSkipListSet,它显然是通过多个线程访问的。现在,基础对象的compareTo方法使用的值会随着时间的推移而改变。因此,我想“更新”列表的顺序(通过使用它或类似的方法)

但是,java.util.Collections.sort(list)不起作用,仅仅重建列表可能太慢(并且会破坏整个并发性证明)。有没有其他的解决方案我应该考虑


它不必导致最佳排序(对于并发性和不断变化的值来说,这几乎是不可能的)。只要任何remove/add调用保持线程无关(在排序时重建列表时,这将是一个真正的问题),接近最优就足够了

Java API中的这些类型的集合不支持可变元素(即compareTo方法更改的元素)。因此,唯一的方法是以原子的方式重新组装一个新的列表,或者按照Will的建议,您可以执行元素的移除、变异和重新插入

HashSet也有同样的问题-哈希桶是在插入对象时计算的,如果您更改对象的哈希代码,则无法执行
set.contains(…)

确切地说,ConcurrentSkipListSet和HashSet等集合在插入和删除时执行比较/散列。“支持”可变元素的唯一集合不会根据元素的状态(例如ArrayList)执行特殊的插入逻辑

对于设置的接口状态:

注意:如果将可变对象用作集合元素,则必须非常小心。当对象是集合中的元素时,如果对象的值以影响相等比较的方式更改,则不会指定集合的行为。这种禁止的一种特殊情况是,不允许集合本身包含为元素

以及用于分拣数据集接口状态的:

请注意,如果排序集要正确实现set接口,则排序集维护的排序(无论是否提供显式比较器)必须与equals一致。(请参阅Comparable interface或Comparator interface以获得与equals一致的精确定义。)这是因为Set interface是根据equals操作定义的,但排序集使用其compareTo(或compare)方法执行所有元素比较,因此此方法认为相等的两个元素是,从排序集的角度来看,相等。即使排序集的顺序与equals不一致,排序集的行为也是定义良好的;它只是没有遵守Set接口的总合同


每次编辑项目时,如果其排序顺序可能会发生更改,则必须将其从列表中删除,然后更改键,然后重新插入



Azul Systems的Cliff Click博士介绍了如何使用墓碑之类的工具实现无锁哈希表。如果您打算编写自己的跳过列表/树,以便将项目重新排序为单个操作(希望更快),那么您也可能会采用这种无锁的方式。请务必分享您的结果:)

这是一个有趣的问题,但很难推断出这是正常的故事!场景是什么,为什么比较运算符是变量?知道了这一点,可能会有一种完全不同的方法。听起来元素是可变的。对象在数据结构中的位置与它所在的位置不同。为了改变它的位置,你必须改变结构。我会考虑重构你的集合,这样对象就不会改变。这意味着使用多个集合,以便其中一个集合中的元素可以相对于另一个集合中的元素“移动”。您是否有参考,在哪里可以给出指导原则?您说这些类型中的“大多数”。你是说“全部”吗?如果没有:哪些类型的集合/do/支持可变元素?@GauravSaxena我添加了一些Java API引用-这足够了吗?谢谢你澄清了你的答案。但是,尽管它/确实/提供了一个正式的理由来解释我为什么要问这个问题,但它并没有提供一个解决方案:(+1:必须非常清楚地说明这一点。您不能使用by compareTo()或hashCode()和equals()更改任何字段的值)对于散列集合,我们希望它能够工作。因此,最好将这些字段设置为最终字段。更相关的问题是-当散列集合需要这样的功能时,我们如何维护排序顺序?这就是原始问题的目的。@GauravSaxena我们通过删除、修改键,然后重新输入来维护排序顺序nserting@Will:此时此刻,你的答案与我想要的最接近。它大概是我自己找到的,所以我仍然希望有一个更令人满意的解决方案。如果没有,你的答案将是一个有趣的旁白,在我的游戏引擎中,甚至在我的hellepoll Web服务器中,我一直使用自定义排序c确实支持显式移动项目的容器-即尝试在一个步骤中高效地执行删除、更新和插入操作。但是,我怀疑这是否真的值得,如果您使用Java,您将不得不制作自己的容器,这可能比速度快得多。我很好奇,跳过列表在pr中是否真的那么好听起来像是在做什么?怎么样?你能把它的表现和经典的树相比较吗?