首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >集合,在删除/获取时进行排序

集合,在删除/获取时进行排序
EN

Stack Overflow用户
提问于 2014-03-24 17:59:05
回答 2查看 106关注 0票数 0

在这种情况下,我需要一个threadsafe队列,它在每次调用remove()方法时,只在调用该方法时运行一个排序。这是因为在将对象添加到集合之后,对象可以动态地更改“优先级”。这也需要线程安全。没有必要扩展类似于PriorityBlockingQueue的内容,因为当添加时,它将运行比较函数。我找不到任何这样的集合/队列,所以我尝试通过包装数组列表来实现自己的收集/队列:

代码语言:javascript
复制
public class BlockingSortOnTakeQueue<E> implements Queue<E>
{
    private ArrayList<E> m_list;

    public BlockingSortOnTakeArrayList()
    {
        m_list = new ArrayList<>();
    }


    @Override
    public synchronized E remove() 
    {
        m_list.sort(m_comparator);
        return m_list.remove(0);
    }

    ....

不幸的是,我很难弄清楚如何确保对象类型<E>必须实现可比较的接口,并在尝试排序列表时使用对象compareTo函数(在我的代码中,m_comparator是未完成/占位符)。

是否有人知道只对remove()进行排序的线程安全队列,或者如何修复我的自定义集合的开始,以便使用泛型对象compareTo函数对列表进行排序。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-24 18:08:06

看上去你是按必须的方式做的。若要强制使用Comparable接口,请编写

代码语言:javascript
复制
public class BlockingSortOnTakeQueue<E extends Comparable<E>> implements Queue<E> {
  ...
  @Override
  public synchronized E remove() {
    Collections.sort(m_list);
    return m_list.remove(0);
  }
}

...though --用Collections.sort(m_list, Collections.reverseOrder())进行反向排序和删除最后一个元素可能对您有好处,因为在ArrayList中这样做更快。

最好只是标识最小元素,而不是对整个列表进行排序,这将是O(n)而不是O(n log )。

票数 2
EN

Stack Overflow用户

发布于 2014-03-24 21:44:42

对象可以在将它们添加到集合后动态更改“优先级”。这也需要线程安全。

那么,如果这些“外部因素”在排序算法运行时更改集合中的对象,会发生什么情况?它可能破坏列表,并且示例代码没有显示如何防止它发生。如果要避免这个问题,这些“外部因素”必须与remove()函数在同一个对象上同步。

此外,如果您的代码成功地删除了最高优先级项,然后在您计划对其进行任何操作之前,一个“外部因素”会运行,并导致其他一些仍在集合中的对象具有更高的优先级,这会给您带来问题吗?如果是这样的话,那么不只是同步remove()函数,您需要同步调用remove()并执行操作的任何代码块。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22617080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档