【问题标题】:How do you put {0,0} into an array and able to change it when a if statement is met如何将 {0,0} 放入数组并在遇到 if 语句时更改它
【发布时间】:2019-09-04 14:47:58
【问题描述】:

我的计划是创建一个只有两个值的数组,即 {0,0},因为我想更改它的值以模拟坐标的移动方式。 当随机数分配给 x 时,我想将坐标移动到 (0,1),

假设我有一行 if 循环,

if(x=0){ //I would change the value from {0,0} to {0,1} } 

我试过这样写代码,

public static int x = 0;
public static int y = 0;
public static void randomWalk(int [] moving_point) {
    int r = ThreadLocalRandom.current().nextInt(4);
    if(r == 0) {
        moving_point[x,y] = moving_point[x,y+1];
    }
}

但不正确,

这可能吗?如何? 谢谢!

【问题讨论】:

    标签: java arrays coordinates element


    【解决方案1】:

    最里面的代码必须改成:

    moving_point[1] = moving_point[1] + 1;

    1 为您提供moving_point 数组中“y”位置的索引,但不会修改您的字段。

    【讨论】:

      【解决方案2】:
      public static int x = 0;
      public static int y = 0;
      public static void randomWalk(int [] moving_point) {
          int r = ThreadLocalRandom.current().nextInt(4);
          if(r == 0) {
              moving_point[x,y] = moving_point[x,++y];   
          }
      }
      

      我建议在这种情况下使用 Pre-Increment(++x)。 Pre-increment 表示变量在表达式中计算之前递增。

      【讨论】:

        【解决方案3】:
        moving_point[1]++; 
        

        在for里面。

        我建议您不要将数组传递给函数,因为该方法不能假定它的长度。您可以传递两个整数或传递一个类,已经实现了几个:Point 只是一个示例。

        【讨论】:

          【解决方案4】:

          在 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());
          

          【讨论】:

          • 感谢您的建议!但是,我的计划也是将路径或坐标保存到 ArrayList,所以每当我想移动到下一个点时,我将能够检查 ArrayList 中是否保存了重复的坐标,然后我可以移动到另一点,没有回头路,就像自我避免的随机游走一样。是你设置坐标的方式还是我设置坐标的方式更有可能?
          • 我已添加到我的答案中。可以使用数组,但您不能将LinkedHashSet 的内置效率与equalshashCode 结合使用,因为您无法在数组上覆盖它们,因此将仅限于对象相等,即包含相同数字的数组不会相等,除非它们是完全相同的实例。换句话说:使用数组的可读性要差得多,甚至不是“面向对象”。
          猜你喜欢
          • 2014-01-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-25
          • 2012-05-13
          相关资源
          最近更新 更多