【问题标题】:How to map sorted index back to original index for collection I'm sorting如何将排序索引映射回我正在排序的集合的原始索引
【发布时间】:2010-09-17 10:37:48
【问题描述】:

我有一个集合 (List),我需要对它进行左右排序。那部分很容易。然后我想以 original 的顺序遍历 Rectangle,但很容易在排序的集合中找到它们的索引。 indexOf() 不起作用,因为我可能有许多相等的对象。我不禁觉得应该有一个简单的方法来做到这一点。

【问题讨论】:

    标签: java sorting collections


    【解决方案1】:

    另一种方法是对索引数组进行排序,而不是对原始列表进行排序。该数组以标识数组 a[0] = 0、a[1] = 1 等开始,然后使用自定义比较器/排序来获取索引数组。不需要太多额外空间,因为您只有一个额外的整数数组而不是另一个集合。

    【讨论】:

      【解决方案2】:

      我找到了一个解决方案 - 但也许有一个更整洁/更优化的解决方案。

      List<Rectangle> originalRects = ...;
      
      /* record index of each rectangle object.
       * Using a hash map makes lookups efficient,
       * and using an IdentityHashMap means we lookup by object identity
       * not value.
       */
      IdentityHashMap<Rectangle, Integer> originalIndices = new IdentityHashMap<Rectangle, Integer>();
      for(int i=0; i<originalRects.size(); i++) {
          originalIndices.put(originalRects.get(i), i);
      }
      
      /* copy rectangle list */
      List<Rectangle> sortedRects = new ArrayList<Rectangle>();
      sortedRects.addAll(originalRects);
      
      /* and sort */
      Collections.sort(sortedRects, new LeftToRightComparator());
      
      /* Loop through original list */
      for(int i=0; i<sortedRects.size(); i++) {
          Rectangle rect = sortedRects.get(i);
          /* Lookup original index efficiently */
          int origIndex = originalIndices.get(rect);
      
          /* I know the original, and sorted indices plus the rectangle itself */
      ...
      

      【讨论】:

      • 这就是我的建议。
      【解决方案3】:

      克隆列表并对其中一个进行排序。对同一个对象有两个引用对于 indexOf() 来说并不重要,因为指向同一个对象的指针是相同的,你无法区分它们。 如果您有两个相等但不相同的对象,并且您确实想区分它们,那么您确实遇到了问题,因为 indexOf() 正在使用 equal 方法。 在这种情况下,最好的解决方案可能是简单地遍历列表并检查对象身份 (==)。

      【讨论】:

        【解决方案4】:

        如果您没有数以万计的对象,您可以将它们存储在两个单独的集合中,一个是原始的,一个是排序的。请记住,Java 中的集合类仅存储对对象的引用,因此它不会像看起来那样占用大量内存。

        【讨论】:

        • 没那么简单。假设我有这些集合(a 和 b)。如果我遍历 a,我如何在 b 中找到该对象?我不能做 indexOf (可能有两个相等的矩形),反正效率很低。
        • 如果你正在搜索一个排序的集合,只需将其设为一个数组并进行二进制搜索,O(lg n)。
        猜你喜欢
        • 2012-02-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-04
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多