【问题标题】:Fastest way to find an item in a sorted ArrayList在已排序的 ArrayList 中查找项目的最快方法
【发布时间】:2015-11-11 12:33:12
【问题描述】:

在 Java 中,我有一个带有对象列表的 ArrayList。每个对象都有一个只是长数据类型的日期字段。 ArrayList 按日期字段排序。我想在 ArrayList 中插入一个新对象,以便它出现在关于其日期的正确位置。我能看到的唯一解决方案是遍历所有项目并将被插入对象的日期字段与被迭代的对象进行比较,然后在我到达正确位置时将其插入。如果我必须插入大量记录,这将是一个性能问题。

有哪些可能的方法来提高这种性能?也许 ArrayList 不是最好的解决方案?

【问题讨论】:

  • 你可以使用二分查找找到插入点。
  • 具体来说,Collections.binarySearch()。但是不,ArrayList 很可能不是最好的结构。
  • 您可能需要考虑使用不同的集合类型,可能是TreeSet,并使您的项目Comparable。然后你就可以开箱即用了。

标签: java


【解决方案1】:

我会说你的说法是正确的:

也许 ArrayList 不是最好的解决方案

就个人而言,我认为树形结构更适合于此。特别是二叉搜索树,它按对象的日期时间排序。创建树后,您可以使用二进制搜索,这将花费 O(log n) 时间。

【讨论】:

  • 在 Java 中有一个 TreeSet 就是为了这个目的。
【解决方案2】:

二分查找 + O(n) 插入是否对您不利,至少取决于以下几点:

  • 列表大小,
  • 访问模式(主要是插入或主要读取),
  • 空间考虑(ArrayList 比其他替代方案更紧凑)。

鉴于这些因素的存在及其相当复杂的相互作用,在通过测量发现当前设计有多糟糕之前,您不应切换到基于二叉搜索树的解决方案。这种转变甚至可能会让你的情况变得更糟。

【讨论】:

    【解决方案3】:

    首先您应该使用以下方法对 ArrayList 进行排序:

    ArrayList<Integer> arr = new ArrayList<>();
    ...
    Collections.sort(arr);
    

    那么你的答案是:

    int index = Collections.binarySearch(arr , 5);
    

    【讨论】:

      【解决方案4】:

      我会考虑使用TreeSet 并将您的项目设为Comparable。然后你就可以开箱即用了。

      如果这不可能,我会通过 Collections.binarySearch(...) 搜索索引。

      编辑:在开始优化之前确保性能是一个问题

      【讨论】:

      • 在知道这是个问题之前不要考虑性能?!绝对不同意你的观点。这就像说如果你认为自己不需要它,就不要拿一根结实的绳子去攀岩。最好是第一次生成高效的代码,而不是在出现问题后返回并更改它。
      • 真正的建议是“始终考虑性能,但不要猜测---衡量”。
      • Marko 做对了。我刚刚看到很多人为了性能提升而做丑陋的事情,结果变得不需要或根本没有性能优势......
      • @JanZyka 是的,但 OP 特别提到他想提高性能,即使是以使用 ArrayList 以外的东西为代价。
      • @EvanBechtol:是的。因此,我首先建议使用 TreeSet。我对性能的最后评论根本没有必要。同意
      猜你喜欢
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 2016-06-09
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多