我有两个数组表示3D空间中的点,position[]
表示XYZ,colors[]
表示RGB,两者的大小均为3*total_points
(例如position[0]
为{{1} },X
为Y,position[1]
为点0的Z坐标,position[2]
为红色值,color[0]
为绿色,color[1]
为蓝色)。
我需要做的是基本上按3个步骤对所有点进行排序:
color[2]
)position[0]
)position[1]
)在Java中执行此操作的最有效方法是什么?
我想到的只是做一个类似冒泡的方法和交换,并做三次。
position[2]
答案 0 :(得分:1)
面向对象编程的一个关键点是抽象。要实现它,您应该创建一个表示彩色3D点的类,例如:
public class Point {
private final int x;
private final int y;
private final int z;
private int red;
private int green;
private int blue;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public String toString() {
return "(" + x + ", " + y + ", " + z + ")";
}
// TODO getters for x, y and z, plus getters & setters for red, green and blue
}
注意:我添加了一个非常有用的toString()
方法,可以帮助您调试代码。吸气剂和制定者留下来作为练习:)
现在,如果你有一个点数组,即Point[] points
,你可以使用内置的Arrays.sort
实用程序方法,它接受一个数组和一个Comparator<Point>
:
Point[] points = new Point[] {
new Point(2, 3, 1),
new Point(2, 1, 4),
new Point(2, 1, 5) };
System.out.println(Arrays.toString(points)); // [(2, 3, 1), (2, 1, 4), (2, 1, 5)]
Comparator<Point> comparator = Comparator.comparingInt(Point::getX)
.thenComparingInt(Point::getY)
.thenComparingInt(Point::getZ);
Arrays.sort(points, comparator);
System.out.println(Arrays.toString(points)); // [(2, 1, 4), (2, 1, 5), (2, 3, 1)]
注意:我正在使用Arrays.toString
实用程序方法来创建一个人类可读的数组字符串表示。
注意Comparator<Point> comparator
变量的定义:我在说我想要一个比较器,它将根据int
方法返回的Point.getX()
值对点进行排序,然后,如果相等,则顺序将由int
方法返回的Point.getY()
值确定,最后,如果仍然相等,则顺序将由{返回的int
值确定{1}}方法。这就是Comparator.comparingInt
和Comparator.thenComparingInt
方法的用途。
答案 1 :(得分:-2)
正如在另一个答案中提到的,抽象是一个关键点(即从你的三个整数数组中,它们松散地表示一组点到一组实际点)。这样,每次处理时总是有三个预期的坐标。
为了进一步改善答案,你可能会从更多分离中获益:
class Point {
int x, y, z; // plus getters/setters
}
class Color {
int r, g, b; // dito
}
class ColoredPoint {
Point point;
Color color;
}
现在,当您不需要它们时,您可以将点和颜色分开,但是当您这样做时(根据原始问题IIUC中的需要),您可以将它们分开。这被称为“关注分离” - 空间中的位置和颜色是不同的野兽,最好将它们分开。
关于排序,您还可以使用不同的比较器进行各种排序。
Comparator<Point> pointComparator = Comparator.comparingInt(Point::getX)
.thenComparingInt(Point::getY)
.thenComparingInt(Point::getZ);
// and
Comparator<Color> colorComparator = Comparator.comparingInt(Color::getR)
.thenComparingInt(Color::getG)
.thenComparingInt(Color::getB);
因为您使用合成将Point和Color组合在一起,所以如果需要,您可以为ColoredPoint重用这些比较器:
Comparator<ColoredPoint> cpComparator =
Comparator.comparing(ColoredPoint::getPoint, pointComparator)
.thenComparing(Comparator.comparing(ColoredPoint::getColor, colorComparator));
这比我之前的回答更好,看起来像这样:
class Point implements Comparable<Point> {
int x, y, z;
// you can also create a separate Comparator<Point>
// to move the compare code outside of Point
int compareTo(Point other) {
// compare by position in space
int result = this.x - other.x;
result = (result == 0) ? result : this.y - other.y;
result = (result == 0) ? result : this.z - other.z;
return result;
}
Point[] arrayOfPoints = //...
Arrays.sort(arrayOfPoints);
// or
List<Point> listOfPoints = //...
Collections.sort(listOfPoints);
同样由于关注点的分离,这一点并不需要知道你希望如何排序。