我试图按字典顺序排列矩形。 (x,y,宽度,高度)

时间:2014-03-01 22:03:45

标签: java comparator lexicographic

如果矩形具有相同的x值,则比较y值,然后检查宽度和高度,依此类推。

public class RectangleTester
{
    public static void main(String[] args)
    {
        ArrayList<Rectangle2D> list = new ArrayList<>();
        list.add(new Rectangle2D.Double(100,100,50,50));
        list.add(new Rectangle2D.Double(120,80,54,75));
        list.add(new Rectangle2D.Double(85,95,60,55));
        list.add(new Rectangle2D.Double(100,95,55,55));
        list.add(new Rectangle2D.Double(100,95,55,52));

        System.out.println("\nUnsorted Rectangles:");
        for (Rectangle2D temp : list)
            System.out.println(temp.toString() + " Y: " + temp.getY());

这是我的逻辑全部扭曲的地方。在比较具有相同x值或y值的2个矩形时,我不知道为什么比较器没有正确列出正确的顺序。

Comparator<Rectangle2D> comp = new
            Comparator<Rectangle2D>()
            {
                public int compare(Rectangle2D r1, Rectangle2D r2)
                {
                    Double r1X = r1.getX();
                    Double r2X = r2.getX();
                    Double r1Y = r1.getY();
                    Double r2Y = r2.getY();
                    Double r1Width = r1.getWidth();
                    Double r2Width = r2.getWidth();
                    Double r1Height = r1.getHeight();
                    Double r2Height = r2.getHeight();

                    if (r1X == r2X && r1Y == r2Y && r1Width == r2Width && r1Height != r2Height)
                        return r1Height.compareTo(r2Height);
                    else if (r1X == r2X && r1Y == r2Y && r1Width != r2Width)
                        return r1Width.compareTo(r2Width);
                    else if (r1X == r2X && r1Y != r2Y)
                        return r1Y.compareTo(r2Y);
                    else
                        return r1X.compareTo(r2X);
                }
            };

        Collections.sort(list, comp);

        System.out.println("\nSorted Rectangles:");
        for (Rectangle2D temp : list)
            System.out.println(temp.toString());
    }
}

我的输出显示如下:

Unsorted Rectangles:

java.awt.geom.Rectangle2D$Double[x=100.0,y=100.0,w=50.0,h=50.0] Y: 100.0
java.awt.geom.Rectangle2D$Double[x=120.0,y=80.0,w=54.0,h=75.0] Y: 80.0
java.awt.geom.Rectangle2D$Double[x=85.0,y=95.0,w=60.0,h=55.0] Y: 95.0
java.awt.geom.Rectangle2D$Double[x=100.0,y=95.0,w=55.0,h=55.0] Y: 95.0
java.awt.geom.Rectangle2D$Double[x=100.0,y=95.0,w=55.0,h=52.0] Y: 95.0

Sorted Rectangles:

java.awt.geom.Rectangle2D$Double[x=85.0,y=95.0,w=60.0,h=55.0]
java.awt.geom.Rectangle2D$Double[x=100.0,y=100.0,w=50.0,h=50.0]
java.awt.geom.Rectangle2D$Double[x=100.0,y=95.0,w=55.0,h=55.0]
java.awt.geom.Rectangle2D$Double[x=100.0,y=95.0,w=55.0,h=52.0]
java.awt.geom.Rectangle2D$Double[x=120.0,y=80.0,w=54.0,h=75.0]

如您所见,矩形使用x值正确排序,但是当多个矩形具有相同的x值时,排序无法按正确的顺序排列。我用我的if语句上的逻辑拉出我的头发我只需要另一组眼睛。

1 个答案:

答案 0 :(得分:2)

第一个错误,您要将对象与==进行比较。 ==比较引用,而不是值。

第二个错误,您的逻辑错误,并且不必要的复杂。只需按照您的描述实现它:如果矩形具有相同的x值,则比较y值

int result = r1X.compareTo(r2X);
if (result == 0) {
    result = r1Y.compareTo(r2Y);
}
if (result == 0) {
    result = r1Width.compareTo(r2Width);
}
if (result == 0) {
    result = r1Height.compareTo(r2Height);
}
return result;

使用Guava,可以通过

轻松实现
return ComparisonChain.start()
                      .compare(r1X, r2X)
                      .compare(r1Y, r2Y)
                      .compare(r1Width, r2Width)
                      .compare(r1Height, r2Height)
                      .result();

使用Java 8,它会更清晰:

Comparator<Rectangle> comparator = 
    Comparator.comparing(Rectangle::getX)
              .thenComparing(Rectangle::getY)
              .thenComparing(Rectangle::getWidth)
              .thenComparing(Rectangle::getHeight)