【问题标题】:Sorting a CopyOnWriteArrayList对 CopyOnWriteArrayList 进行排序
【发布时间】:2014-08-19 18:45:39
【问题描述】:

我需要在多线程环境中维护一个对象列表。我已经阅读了有关CopyOnWriteArrayList 的信息,这似乎是一种选择。问题是,我也需要对列表进行排序。我不能将Collections.sort() 用于CopyOnWriteArrayList,因为它不支持set() 操作。我发现了几种对 CopyOnWriteArrayList 进行排序的方法。但就性能而言,它们看起来并不好。

我的问题:在这种情况下是否有另一种数据结构可以派上用场?基本上,我需要在多线程环境中保留一个排序列表。列表适配器将使用该数据结构。所以,它应该提供诸如“get(position)”之类的方法。

我最近读到了另一个数据结构ConcurrentSkipListSet。谁能解释一下它的优缺点是什么?它适合我的问题吗?

【问题讨论】:

  • 一个Set 维护着一个独特对象的集合。在SortedSet 的情况下,相等条件定义为a.compareTo(b) == 0Set 保持集合中没有两个对象相等的不变量。如果这符合您的目的,那么ConcurentSkipListSet 是完美的。如果没有,那么使用Collections.sort 并且手动同步会非常慢 - 你需要自己的数据结构。
  • 您还没有解释是什么让 CopyOnWriteArrayList 成为多线程环境中的正确选择。如果没有这些信息,就很难提出替代数据结构。
  • @BoristheSpider 谢谢!我总是可以覆盖我的对象中的 equals() 方法以使其适合集合,所以我认为这不会是一个问题。我尝试使用ConcurentSkipListSet。现在,有一个新问题。由于这是一个 SortedSet,它不提供 .get(position) 方法,当我想在我的列表适配器中使用数据结构时需要该方法。看起来我需要编写自己的自定义数据结构。
  • @Chan 我提到了这个要求。我在多线程环境中工作。我需要维护一个可排序的对象列表。每当在列表中插入任何对象时,我都应该能够对列表进行排序。 CopyOnWriteArrayList 看起来很接近满足要求,除了排序问题。
  • 是的,Set 未编入索引。它也不使用equals,正如我所指出的——它使用compareToSortedSetList非常不同。您应该能够在 ArrayList 上编写一个简单的包装器,该包装器使用 ReentrantReadWriteLock 和插入排序的变体来实现 O(n) add(摊销)。如果您需要比这更快的性能,您将不得不查看更高级的树/堆结构。

标签: java android sorting data-structures


【解决方案1】:

我知道你问的是性能,我不确定我的方法在这方面的效果如何,但这是我使用的:

List arrayList = Arrays.asList(cowArrayList.toArray());
Collections.sort(arrayList, new MyComparator());
cowArrayList.clear();
cowArrayList.addAll(arrayList);

【讨论】:

  • 由于 Collections.sort(List) 创建了一个临时数组,您可以通过跳过该步骤并直接使用数组来节省一点内存(和时间):Object[] arr = cowArrayList.toArray(); Arrays.sort(arr); 如果您可以使用 Java 8,然后就做cowArrayList.sort(comparator);
【解决方案2】:

解决方案1:如果要在插入每个元素的过程中对列表进行排序,可以进行二分查找,每次都将元素添加到已排序的位置。假设列表总是排序的。请看http://www.javacreed.com/sorting-a-copyonwritearraylist/

【讨论】:

  • 您引用的解决方案不是线程安全的,因此如果我们需要线程安全列表实现则无用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 2018-08-02
  • 2015-04-11
  • 2011-06-01
  • 1970-01-01
相关资源
最近更新 更多