Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为数组编写一个可比较的数组。排序点_Java_Arrays_Comparable_Points - Fatal编程技术网

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));
    }
});