【问题标题】:Updating an object by Reference (Suduko)通过引用更新对象(数独)
【发布时间】:2013-03-11 14:50:57
【问题描述】:

我有一个数独解谜器,需要我们使用递归。问题是我检查可用空间的布尔值应该通过引用更新当前位置,但事实并非如此。这是什么原因造成的?

    public boolean solve()
{
    Coordinate current = new Coordinate(); 

    if (findEmptyGridSlot(current)) {   // THE ERROR IS HERE **********  THIS IS SHOWING (0,0) STILL ******************

        for (int number = 1; number <= 9; number++)  
            if (canPlaceNumber(current, number)) { 
                grid[current.getRow()][current.getColumn()] = number; 

                if (solve()) 
                    return true; 

                grid[current.getRow()][current.getColumn()] = 0; 
            } return false;
    }else
        return true;

}

private boolean findEmptyGridSlot(Coordinate coordinate)
{
    boolean found = false;

    try{
        while (!found) 
        {
            if (grid[coordinate.getRow()][coordinate.getColumn()] == 0)
                found = true;
            else
                coordinate = coordinate.next(); // *****This is supposed to update the current coordinate ******
        }
    }catch (Exception e){
        //CREATE No Empty Cells Exception
    } 
    return found;
}

public Coordinate next()
{
    Coordinate result = new Coordinate(row, column);

    result.column++;
    if (result.column > MAX_COORDINATE)
    {
        result.column = MIN_COORDINATE;
        result.row++;
        if (result.row > MAX_COORDINATE) result = null;
    }

    return result;
}

【问题讨论】:

    标签: java oop object pass-by-reference


    【解决方案1】:

    Java 按值传递。这意味着您将获得坐标参考的副本。如果您将该副本指向一个新对象(即coordinate = coordinate.next),您只是在更改本地副本。现在,另一方面,如果您更改了您的变量所引用的对象的属性(例如 coordinate.x = foocoordinate.setX(foo)),则该更改将对您的方法的调用者可见。

    【讨论】:

      【解决方案2】:

      jpm 是正确的,但我第一次看错了,所以我要努力澄清

      private boolean findEmptyGridSlot(Coordinate coordinate)
      

      引用是按值传递的。在这些术语中,“坐标”是一个装有一张纸的盒子,在这张纸上写着一个地址。坐标是一个只属于这个方法的盒子,它有自己的一张纸(很多张纸上可能写着相同的地址)

      我们可以在这个框中查看并将东西“邮寄”到纸上写的地址,但是当我们说

      coordinate=something
      

      这意味着在一张新纸上写下“某物”的地址。扔掉旧纸。

      此操作绝不会影响第一张纸上有地址的原始“房子”。当我的朋友乔恩更新他的通讯录时,不管他写什么,我仍然住在我的房子里。

      因此,如果坐标有一些简单的子结构(例如 x 和 y),您可以“发布”一条指令以将 x 和 y 更改为等于“下一个”。

      或者作为 hack,您可以将 Coordinate 包含在另一个对象中,这样您就可以向它发布指令以更改 hack 类指向的内容

      cmets中引用的测试代码:

      public class Test {
      
          public static void main(String args[]){
              String bareMinObject="start";
              changeString(bareMinObject);
              System.out.println(bareMinObject); //Prints start, change string has no effect
      
          }
      
          public static void changeString(String input){
              String temp="end";
              input=temp;
      
          }
      
      }
      

      【讨论】:

      • 当你调用 findEmptyGridSlot(input) 时,它所做的就是将输入的地址复制到一张新纸上,并将那张纸交给 findEmptyGridSlot
      • 我创建了一个临时变量并将其设置为 = 坐标.next() 然后设置坐标 = temp;问题解决了!
      • 你完全确定它有效吗?因为我读它的方式真的不应该。在我的主要答案中查看我认为的等效代码(因此格式正确)。
      • 除非您的意思是在solve() 方法中而不是在findEmptyGridSlot 中执行此操作。作为一般规则,在方法中使用 = 只会影响方法内的事物,使用 .可能会影响底层对象。
      猜你喜欢
      • 2012-01-26
      • 2021-08-19
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 2021-08-22
      • 1970-01-01
      • 2016-01-07
      • 2017-08-17
      相关资源
      最近更新 更多