如何首先按x排序数组或ArrayList <point> ASC,然后按y?</point>

时间:2010-04-30 01:46:50

标签: java c++ sorting comparison

我只想使用Collections.sort或Arrays.sort先按x排序点(Point类),然后按y排序。

我有一个类Ponto,可以像这样实现Comparable:

public int compareTo(Ponto obj) {
        Ponto tmp = obj;
        if (this.x < tmp.x) {
            return -1;
        } else if (this.x > tmp.x) {
            return 1;
        }
        return 0;
    }

但现在我想在x之后按y排序。

如何通过修改上述代码来做到这一点?或者这是一种更好,更“干净”的方法吗? 我还使用这个代码传递给C ++,我在其中使用等效的方法创建了一个名为Point的结构。

2 个答案:

答案 0 :(得分:6)

return 0this.y上使用相同的比较算法替换obj.y

顺便说一句,这里不需要重新分配给tmp。优化后的图片可能如下所示:

public int compareTo(Ponto other) {
    if (this.x == other.x) {
        return (this.y < other.y) ? -1 : ((this.y == other.y) ? 0 : 1);
    } else {
        return (this.x < other.x) ? -1 : 1;
    }
}

答案 1 :(得分:2)

BalusC提供了正确答案:基本上,您优先考虑x而不是y。这是使用嵌套三元运算符编写的变体,它使优先级清晰。

public int compareTo(Ponto other) {
    return
      (this.x < other.x) ? -1 :
      (this.x > other.x) ? +1 :
      (this.y < other.y) ? -1 :
      (this.y > other.y) ? +1 :
      0;
}

另一种方法是,如果您不想为每个优先级方案编写自定义Comparator<T>,则使用 stable 算法进行多种排序。

如果您想按x(主要),然后y(次要)排序,则:

  • 先排序y(!!!)
  • 然后使用稳定排序
  • x进行排序

这渐渐渐渐O(N log N),但当然你正在做多个阶段。当你有很多排序标准时很方便。而不是编写复杂的代码,只需执行多阶段(并且只在必要时才进行优化)。

因此,如果您按优先顺序排序键k1k2k3,...,kM,则可以:

  • 排序kM
  • kM-1
  • 上的稳定排序
  • ...
  • k1
  • 上的稳定排序
  • DONE!

请注意Collections.sort是稳定的。

  

此类保证稳定:由于排序,相同的元素不会被重新排序。