Java 为数组编写一个可比较的数组。排序点
我有以下代码:Java 为数组编写一个可比较的数组。排序点,java,arrays,comparable,points,Java,Arrays,Comparable,Points,我有以下代码: 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
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");
}
}
}
在if()
子句中我需要写什么
编辑:来自评论
条件是我要注意距离的值
在点(0,0)和点(x,y)之间(如果可能的话
实现
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());
}
}
编辑:注释添加了一个建议,根据点与原点的距离(0,0)对点进行排序。这两种机制也很容易实现。点与原点的距离定义为
sqrt(x*x+y*y)
。由于sqrt
是一种不影响排序的单调变换,因此可以忽略它以获得轻微的性能增益
作为可比较的:
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());
}
}
这取决于你想如何比较这两点。 如果您:
- 如果p1更靠近原点(0,0),则将p1置于p2之前
- 如果p1的x坐标在p2之前,则假定p1在p2之前
- 如果p1的x和y坐标的和在p2的坐标之前,则假设p1在p2之前
这里是一个通过点到原点的距离来比较点的代码示例(如果距离相等,则比较点在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;
}
}
公共类MyPoint扩展了Point实现{
公共整数比较对象(对象o){
点p=(点)o;
//注意,如果sqr(x^2+y^2)p.x*p.x+p.y*p.y){
返回1;
}
//如果与原点的距离相同,则比较x和后续y位置。
如果(x>p.x){
返回-1;
}否则如果(xp.y),则为其他情况{
返回-1;
}
返回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;
}
}
公共类MyPoint扩展了Point实现{
公共整数比较对象(对象o){
点p=(点)o;
如果(x>p.x){
返回-1;
}否则如果(xp.y),则为其他情况{
返回-1;
}
返回0;
}
}
您可以使用类中的私有方法计算与原点的距离,如下所示:
private int distanceFromOrigin(Point point) {
return (int) Math.sqrt(Math.pow(point.getX(), 2) + Math.pow(point.getY(), 2));
}
然后可以修改compareTo
方法,以包括两个点的距离之间的比较,如下所示:
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;
}
public int compareTo(对象o){
点p=(点)o;
if(距离原点(p)>距离原点(本)){
返回-1;
}
if(距离原点(p)<距离原点(this)){
返回1;
}
返回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))));
首先使用类中的方法计算到原点的距离,如下所示:
private int distanceFromOrigin(Point point) {
return (int) Math.sqrt(Math.pow(point.getX(), 2) + Math.pow(point.getY(), 2));
}
保留精度值。不要强制转换为INT,因为比较闭合点可能需要INT。对于许多点,作为整数值的距离可能相同
然后比较方法如下
使用compareTo方法设计包装类
我会投票反对你创建子类的方法
MyPoint扩展点实现可比较的
相反,我建议使用Array.sort(T[],Comparator)
方法
使用泰勒制造的比较器
使用Java 8时,您可以非常简洁地编写它,如下所示:
Point[] pointArray = generatePointArray(15);
Arrays.sort(pointArray, Comparator.comparingDouble(p -> p.distance(0, 0)));
对于Java7(及更早版本),您需要使用更详细的语法
使用匿名类:
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));
}
});
Point[]pointArray=generatePointArray(15);
sort(pointArray,new Comparator(){
@凌驾
公共整数比较(点p1,点p2){
返回Double.compare(p1.距离(0,0),p2.距离(0,0));
}
});
那么,您想如何对数组进行排序?首先是什么点?您认为两个点应该如何进行逻辑比较?不要使用原始泛型。使用Comparable
。也许我可以查看x或y值。@在查看x、y值时,这里的顺序是什么?根据点到原点的距离对点进行排序不能在那工作case@nullpointer当然不会,因为这不是我实现的排序标准:-)。但是这项要求没有出现在OP.Ya中的任何地方,不幸的是,它出现在注释中以清除这些要求。@nullpointer只是在注释中看到了讨论(可能应该编辑)
private double distance(Point p) {
return (double) Math.sqrt(Math.pow(p.getX(), 2) + Math.pow(p.getY(), 2));
}
public int compareTo(Object o) {
return new Double(distance(this)).compareTo(distance(Point(p)));
}
Point[] pointArray = generatePointArray(15);
Arrays.sort(pointArray, Comparator.comparingDouble(p -> p.distance(0, 0)));
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));
}
});