【问题标题】:How to keep a List unfragmented (read explanation)如何保持列表不分段(阅读说明)
【发布时间】:2013-11-21 21:35:39
【问题描述】:

我有以下问题(简化为示例)

我有 项目 由其 ID 标识

class Item {
   private int id;
   public int getId(){
      return id;
   }
}

并且我想将它们保留在一个类中(让我们将其命名为 ItemGroup),条件如下:

  • ItemGroup.getItems() 应该返回一个 List<Item> (不需要按项目 ID 排序的列表)
  • 每次我向ItemGroup 添加新项目时,它应该只维护具有较高和连续 id 的项目。一些例子可以更好地解释它:
    • 现有项目= [5,6],itemsToAdd=[7,8],结果=[5,6,7,8]
    • 现有项目= [5,6],itemsToAdd=[8,9],结果=[8,9]
    • 现有项目= [5,6],itemsToAdd=[3,4],结果=[3,4,5,6]
    • 现有项目= [5,6],itemsToAdd=[1,2],结果=[5,6]

目标是实现聊天,其中消息以小数据包的形式从服务器恢复,主要要求是线程拥有最后的消息,而没有碎片线程(缺少消息)。

主要问题出现在客户端,例如,版本 5,服务器版本 1000。客户端恢复最后 10 条消息,找到 ids (90-100] 的项目。在这种情况下,我想要丢弃旧消息,允许用户向上滚动,如果需要可以恢复以前的消息。

我怎样才能有效地实现这一点?我考虑过的选项是:

  1. 使用List<Items>,每次添加新项目(或项目组)时运行 Collections.sort()。然后以递减方式迭代列表,当我检测到 ids 跳跃时丢弃剩余的项目。
  2. 使用 TreeSet,在修改集合后以相同的方式对列表进行碎片整理。方法getItems() 返回一个new ArrayList<Item>(treeSet)
  3. 使用List,每次需要插入项目时,用二分搜索查找正确的位置,将项目插入那里,然后对列表进行碎片整理。在getItems() 方法中返回未修改的列表
  4. 更多解决方案?

谢谢

【问题讨论】:

  • 添加的项目和现有的项目可以相交(即添加[2,3]到[3,4])?
  • 不,物品是独一无二的 =)。感谢您的回答

标签: java android algorithm optimization


【解决方案1】:

从我假设的示例中,我不确定您的 ID 是否唯一。我还假设插入列表和主列表最初都有相应的元素 如果是这样,算法会很简单:

  1. 在插入之前对两个列表进行排序
  2. 比较插入列表中最低(第一个)元素和主列表中最高(最后)元素,如果相差 1 - 插入到末尾,如果相差更多 - 替换主列表,返回
  3. 比较插入列表中的最高元素和主列表中的最低元素,如果它们相差 1 - 插入到开头,如果它们相差超过 1 - 丢弃插入的列表。

该算法具有 O(n) 的最佳性能(O(1) 用于值比较,O(n) 用于元素插入),只要没有人弄乱列表并且它们总是被排序,这将始终实现。

【讨论】:

    猜你喜欢
    • 2019-06-04
    • 2020-10-02
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多