在 Java 中表示坐标的可以说是“更正确”的方法是创建一个 Coordinate 类:
public class Coordinate {
private int x;
private int y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void moveUp(int distance) {
y += distance;
}
public void moveDown(int distance) {
y -= distance;
}
public void moveLeft(int distance) {
x -=distance;
}
public void moveRight(int distance) {
x += distance;
}
@Override
public String toString() {
return String.format("{%d,%d}", x, y);
}
}
public static void randomWalk(Coordinate point) {
int r = ThreadLocalRandom.current().nextInt(4);
if(r == 0) {
point.moveUp(1);
}
}
这可以让你在你的软件中简洁地表示多个坐标,也可以让你编写一些非常直观的方法,比如上面例子中的moveUp/Down/Left/Right。
这样做的另一个很好的理由是您的数组没有任何限制,因此有人可能会无意中添加第三个、第四个或第五个值,这显然是没有意义的。使用单独的类使代码更加自文档化。
回到示例,您现在可以运行:
Coordinate c = new Coordinate(0, 0);
System.out.println(c); // prints "{0,0}"
randomWalk(c);
System.out.println(c); // prints "{0,1}" IF you were lucky to get a random 0...
注意:
在这里,坐标空间被解释为就像在学校的图表上一样,向右增加 x 并向上增加 y。在计算机屏幕上,y 空间通常是翻转的(原点是屏幕的左上角),因此作为练习考虑如何纠正它。 (提示,只涉及更改moveUp()和moveDown())
编辑:
根据您的评论,为了能够记录路径,您可能希望使用 LinkedHashMap 而不是 ArrayList (在保持排序的同时查找效率)并通过从每个返回一个新实例使 Coordinate 不可变moveX 操作。您还需要实现equals() 和hashCode()。
public class Coordinate {
private final int x;
private final int y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Coordinate moveUp(int distance) {
return new Coordinate(x, y+distance);
}
public Coordinate moveDown(int distance) {
return new Coordinate(x, y-distance);
}
public Coordinate moveLeft(int distance) {
return new Coordinate(x-distance, y);
}
public Coordinate moveRight(int distance) {
return new Coordinate(x+distance, y);
}
@Override
public String toString() {
return String.format("{%d,%d}", x, y);
}
@Override
public int hashCode() {
//we need to do something a bit more clever than "x+y", otherwise {1,0} might end up with the same hash as {0,1}
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if(this == obj) return true;
if(obj == null) return false;
if(getClass() != obj.getClass()) return false;
Coordinate other = (Coordinate)obj;
if(x != other.x) return false;
if(y != other.y) return false;
return true;
}
}
public class Walker {
private LinkedHashSet<Coordinate> path = new LinkedHashSet<>();
private Coordinate last;
public Walker(Coordinate startingPoint) {
path.add(startingPoint);
last = startingPoint;
}
public Set<Coordinate> getPath() {
return path;
}
public void randomWalk() {
int r = ThreadLocalRandom.current().nextInt(4);
if(r == 0) {
Coordinate nextStep = last.moveUp(1);
if(path.add(nextStep)) {
//Set returns "true" if the item was added, "false" otherwise.
last = nextStep;
} else {
//So if not added, we've already been there.
//take alternative action, retry, whatever...
}
}
}
}
Walker w = new Walker(new Coordinate(0,0));
for(int i=0; i<10; i++) {
w.randomWalk();
}
System.out.println(w.getPath());