我有这段代码:
import java.awt.Point;
import java.util.Arrays;
public class Haupt {
// creates an array of anz Point objects
public static Point[] generatePointArray(int anz) {
Point[] pa = new Point[anz];
for(int i = 0; i < anz; i++) {
int px = (int) (Math.random() * 10);
int py = (int) (Math.random() * 10);
pa[i] = new Point(px,py);
}
return pa;
}
public static void main(String[] args) {
Point[] pointArray = generatePointArray(15);
Arrays.sort(pointArray);
for(int i = 0 ; i < pointArray.length; i++) {
System.out.println("Point: "+pointArray[i] +
" has distance "+pointArray[i].distance(0,0)+
" from origin");
}
}
}
正如你可能看到我想要对一个点数组进行排序,因此我写了(几乎)一个可比的:
import java.awt.Point;
public class MyPoint extends Point implements Comparable {
public int compareTo(Object o)
{
Point p = (Point) o;
if () {
return -1;
}
if () {
return 1;
}
return 0;
}
}
我需要在if()
子句中写一下什么?
编辑:来自评论
条件是我会照看距离的值 点(0,0)和点(x,y)之间(如果这是可能的
)
答案 0 :(得分:1)
您可以使用班级中的私人方法计算与原点的距离:
private int distanceFromOrigin(Point point) {
return (int) Math.sqrt(Math.pow(point.getX(), 2) + Math.pow(point.getY(), 2));
}
然后可以修改compareTo
方法以包括两个Point
的距离之间的比较:
public int compareTo(Object o) {
Point p = (Point) o;
if (distanceFromOrigin(p) > distanceFromOrigin(this)) {
return -1;
}
if (distanceFromOrigin(p) < distanceFromOrigin(this)) {
return 1;
}
return 0;
}
答案 1 :(得分:0)
实施compareTo
方法完全取决于您希望如何对这些点进行排序。一种合理的方法是通过它们的X和Y坐标:
public class MyPoint extends Point implements Comparable<MyPoint> {
public int compareTo(MyPoint o) {
int retVal = Double.compare(getX(), o.getX());
if (retVal != 0) {
return retVal;
}
return Double.compare(getY(), o.getY());
}
}
或者,您可以使用自定义Comparator
,而不是创建自己的实现Comparable
接口的类。使用Java 8的增强功能,它甚至会非常优雅:
Arrays.sort(
pointArray,
Comparator.comparing(Point::getX).thenComparing(Point::getY)
);
编辑:
评论添加了一个建议,即按点与原点(0,0)的距离对点进行排序。这两种机制也很容易实现。点与原点的距离定义为sqrt(x*x + y*y)
。由于sqrt
是一种不会影响排序的单调变换,因此可以省略它以获得轻微的性能提升。
作为Comparaable
:
public class MyPoint extends Point implements Comparable<MyPoint> {
public int compareTo(MyPoint o) {
return Long.compare(getCompareKey(), o.getCompareKey());
}
private long getCompareKey() {
return (getX() * getX()) + (getY() * getY());
}
}
使用自定义Comparator
:
Arrays.sort(
pointArray,
Comparator.comparing(p -> (p.getX() * p.getX()) + (p.getY() * p.getY())
);
答案 2 :(得分:0)
这取决于你想要比较两点的方式。 如果您:
,实施会有所不同可能存在数千种可能的比较!
这里是一个代码示例,通过它们与原点的距离来比较点(如果距离相等,则比较它们在x和y轴上的位置):
注意没有必要计算实际距离来检查哪个点更接近原点。如果计算两个距离的幂,您将使用较少的cpu得到相同的结果(因此可以删除平方根的计算)。您肯定会获得相同的结果,因为距离始终是正数。另外,使用表达式x * x
比使用表达式Math.pow(x, 2)
更快。这种优化在这种情况下很有用,因为几何操作通常涉及数百万个点。
public class MyPoint extends Point implements Comparable {
public int compareTo(Object o) {
Point p = (Point) o;
// Note that if sqr(x^2 + y^2) < sqr(p.x^2 + p.y*2)
// Also x^2 + y^2 < p.x*2 + p.y*2 but you save
// computing cicles
// THis is possible because we are comparing distances,
// it is not necessary to calculate the right distance if
// you need only to know the comparison between them
if (x*x + y*y < p.x*p.x + p.y*p.y) {
return -1;
} else if (x*x + y*y > p.x*p.x + p.y*p.y) {
return 1;
}
// In case of same distance to origin compare x and subsequent y positions.
if (x > p.x) {
return -1;
} else if (x < p.x) {
return 1;
} else if (y < p.y) {
return 1;
} else if (y > p.y) {
return -1;
}
return 0;
}
}
这里有一个可能的实现,它将两个点乘以x坐标,如果它们等于比较y坐标。
public class MyPoint extends Point implements Comparable {
public int compareTo(Object o) {
Point p = (Point) o;
if (x > p.x) {
return -1;
} else if (x < p.x) {
return 1;
} else if (y < p.y) {
return 1;
} else if (y > p.y) {
return -1;
}
return 0;
}
}
答案 3 :(得分:0)
您可以使用lambda比较两个点的x
和y
坐标,例如:
Arrays.sort(points, (Point p1, Point p2) -> p1.getPx() == p2.getPx() ?
p1.getPy() - p2.getPy() : p1.getPx() - p2.getPx());
<强>更新强>
根据问题编辑,您可以使用Sqrt(x2 + y2)
公式计算距离,并在比较两个点时使用它,例如:
Arrays.sort(points, (Point p1, Point p2) -> (int) Math.sqrt(Math.pow(p1.getPx(), 2) +
Math.pow(p1.getPy(), 2) - Math.sqrt(Math.pow(p2.getPx(), 2) + Math.pow(p2.getPy(), 2))));
答案 4 :(得分:0)
首先使用您班级中的方法计算距离原点的距离:
保持精确值。不要转换为INT,因为可能需要比较关闭点。对于许多点,距离作为整数值可能相同。
private double distance(Point p) {
return (double) Math.sqrt(Math.pow(p.getX(), 2) + Math.pow(p.getY(), 2));
}
然后compareTo方法可以如下。
使用为包装类设计的compareTo方法。
public int compareTo(Object o) {
return new Double(distance(this)).compareTo(distance(Point(p)));
}
答案 5 :(得分:0)
我会投票反对你创建子类的方法
MyPoint extends Point implements Comparable<Point>
。
相反,我建议使用Array.sort(T[], Comparator<T>)
方法
用泰勒制作的Comparator<Point>
。
使用Java 8时,您可以非常简洁地编写它:
Point[] pointArray = generatePointArray(15);
Arrays.sort(pointArray, Comparator.comparingDouble(p -> p.distance(0, 0)));
对于Java 7(及更早版本),您需要使用更详细的语法 匿名课程:
Point[] pointArray = generatePointArray(15);
Arrays.sort(pointArray, new Comparator<Point>() {
@Override
public int compare(Point p1, Point p2) {
return Double.compare(p1.distance(0, 0), p2.distance(0, 0));
}
});