2016-04-14 228 views
1

实例化多个相同类型的对象时遇到了一个奇怪的问题。实例化多个相同的对象

我想解析一个新创建的对象到一个LinkedList queue。所以出错的是,它应该将第一个对象tempBoardDirection解析到第一个if语句的队列中,然后将第二个对象tempBoardDirectionLeft解析到队列中。

它出错的部分是它看起来更像是只是改变我的tempBoard对象,因为当我打印出来的字段时,我改变了它在3个对象中总是相同的。

我在哪里做错误,因为它们是指对方?

我想看看tempBoard.robots[0],前后第一个if语句,后并后第二if语句,这是该数据:前第一if语句

  • - java.awt.Point[x=0,y=1]
  • 第一,如果后声明 - java.awt.Point[x=0,y=4]
  • 后第二个如果statmenet - java.awt.Point[x=0,y=0]

这不应该从java.awt.Point[x=0,y=1]更改,因为我正在创建新对象并编辑它们的属性,而不是tempBoard属性。

这是函数的代码段应该解释哪里出了问题:

while(!q.isEmpty()){ 
        Board tempBoard = q.poll(); 
    ​ 
        if(tempBoard.isGoal()) 
         return tempBoard.moves; 
    ​ 
        Endpoints endpoint = tempBoard.possibleEndpointsForRobot(0); 
        System.out.println(tempBoard.robots[0]); 
    ​ 
        if(!visited[endpoint.right.x][endpoint.right.y]){ 
         Board tempBoardDirection = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal); 
         tempBoardDirection.moves = tempBoard.moves; 
         tempBoardDirection.moveRobot(0,Direction.Right); 
         visited[endpoint.right.x][endpoint.right.y] = true; 
         q.add(tempBoardDirection); 
         System.out.println("right: "+tempBoardDirection.robots[0]); 
        } 
    ​ 
        if(!visited[endpoint.left.x][endpoint.left.y]){ 
         Board tempBoardDirectionLeft = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal); 
         tempBoardDirectionLeft.moves = tempBoard.moves; 
         tempBoardDirectionLeft.moveRobot(0,Direction.Left); 
         visited[endpoint.left.x][endpoint.left.y] = true; 
         q.add(tempBoardDirectionLeft); 
         System.out.println("Left: "+tempBoardDirectionLeft.robots[0]); 
        } 
    ​ 

这里是它失败的整体功能:

public String computeSolution() throws Exception { 
      Queue<Board> q = new LinkedList<>(); 
​ 
      q.add(this.board); 
      this.visited[this.board.robots[0].x][this.board.robots[0].y] = true; 
​ 
      int i = 0; 
​ 
      while(!q.isEmpty()){ 
       Board tempBoard = q.poll(); 
​ 
       if(tempBoard.isGoal()) 
        return tempBoard.moves; 
​ 
       Endpoints endpoint = tempBoard.possibleEndpointsForRobot(0); 
       System.out.println(tempBoard.robots[0]); 
​ 
       if(!visited[endpoint.right.x][endpoint.right.y]){ 
        Board tempBoardDirection = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal); 
        tempBoardDirection.moves = tempBoard.moves; 
        tempBoardDirection.moveRobot(0,Direction.Right); 
        visited[endpoint.right.x][endpoint.right.y] = true; 
        q.add(tempBoardDirection); 
        System.out.println("right: "+tempBoardDirection.robots[0]); 
       } 
​ 
       if(!visited[endpoint.left.x][endpoint.left.y]){ 
        Board tempBoardDirectionLeft = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal); 
        tempBoardDirectionLeft.moves = tempBoard.moves; 
        tempBoardDirectionLeft.moveRobot(0,Direction.Left); 
        visited[endpoint.left.x][endpoint.left.y] = true; 
        q.add(tempBoardDirectionLeft); 
        System.out.println("Left: "+tempBoardDirectionLeft.robots[0]); 
       } 
​ 
       if(!visited[endpoint.up.x][endpoint.up.y]){ 
        System.out.println("works up"); 
        Board tempBoardDirection = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal); 
        tempBoardDirection.moves = tempBoard.moves; 
        tempBoardDirection.moveRobot(0,Direction.Up); 
        visited[endpoint.up.x][endpoint.up.y] = true; 
        q.add(tempBoardDirection); 
       } 
​ 
       if(!visited[endpoint.down.x][endpoint.down.y]){ 
        System.out.println("works down"); 
        Board tempBoardDirection = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal); 
        tempBoardDirection.moves = tempBoard.moves; 
        tempBoardDirection.moveRobot(0,Direction.Down); 
        visited[endpoint.down.x][endpoint.down.y] = true; 
        q.add(tempBoardDirection); 
       } 
       //System.out.println(tempBoard.moves); 
       i++; 
      } 
​ 
      System.out.println("num of loops: "+i); 
      throw new Exception("no solution"); 
     } 

更新1:

这是董事会班,按要求我也应该在这里。

public class Board { 
    public static final char GOAL_CHAR = 'G'; 
    public static final char WALL_CHAR = '#'; 
    public static final char EMPTY_CHAR = ' '; 
​ 
    public char[][] board; 
    public int size; 
    public Point[] robots; 
    public Point goal; 
    public String moves = ""; 
    public boolean[][] visited; 
​ 
    public Board(char[][] board, Point[] robots, Point goal) { 
     this.board = board; 
     this.size = board.length; 
     this.robots = robots; 
     this.goal = goal; 
     this.visited = new boolean[this.size][this.size]; 
    } 
​ 
​ 
    public Integer getCurrentRobotFromQueue(Queue q) { 
     return IntStream.range(0, robots.length).filter(i -> q.element().equals(robots[i])).findFirst().getAsInt(); 
    } 
​ 
    public boolean isGoal() { 
     return this.robots[0].equals(this.goal); 
    } 
​ 
    public Endpoints possibleEndpointsForRobot(int robot) { 
     assert robot < robots.length; 
​ 
     Point up = pointAfterMovingRobot(robot, Direction.Up); 
     Point down = pointAfterMovingRobot(robot, Direction.Down); 
     Point left = pointAfterMovingRobot(robot, Direction.Left); 
     Point right = pointAfterMovingRobot(robot, Direction.Right); 
​ 
     return new Endpoints(up, down, left, right); 
    } 
​ 
    public Point pointAfterMovingRobot(int robot, Direction m) { 
     assert robot < robots.length; 
​ 
     Point pos = new Point(robots[robot]); 
     int drow = 0, dcol = 0; 
​ 
     if (m == Direction.Up) { 
      drow = -1; 
     } else if (m == Direction.Down) { 
      drow = 1; 
     } 
​ 
     if (m == Direction.Left) { 
      dcol = -1; 
     } else if (m == Direction.Right) { 
      dcol = 1; 
     } 
​ 
     while (withinBoard(pos.x+drow, pos.y+dcol) && 
       (board[pos.x+drow][pos.y+dcol] == EMPTY_CHAR 
         || board[pos.x+drow][pos.y+dcol] == GOAL_CHAR)) { 
      pos.translate(drow, dcol); 
     } 
​ 
     return pos; 
    } 
​ 
    public void moveRobot(int robot, Direction d) { 
     assert robot < robots.length; 
​ 
     Point from = robots[robot]; 
     Point to = pointAfterMovingRobot(robot, d); 
     board[from.x][from.y] = EMPTY_CHAR; 
     robots[robot] = to; 
     board[to.x][to.y] = (char) ('0' + robot); 
​ 
     //add move to moves. 
​ 
     this.moves += robot+d.toString()+", "; 
    } 
​ 
    private boolean withinBoard(int x, int y) { 
     return x >= 0 && x < size && y >= 0 && y < size; 
    } 
​ 
    public String toString() { 
     StringBuilder sb = new StringBuilder(size * size); 
​ 
     for (int i = 0; i < board.length; i++) { 
      sb.append(board[i]); 
      sb.append(System.getProperty("line.separator")); 
     } 
​ 
     return sb.toString(); 
    } 
} 

回答

1

我找到了解决方案。 问题是我需要在创建对象的新实例之前创建信息的副本。

我解决的方式是通过做一个新的超类,并且做这样的:

public Board(Board tempBoard){ 
    this.board = new char[tempBoard.board.length][tempBoard.board.length]; 
    this.robots = new Point[tempBoard.robots.length]; 
    System.arraycopy(tempBoard.board, 0, board, 0, tempBoard.board.length); 
    System.arraycopy(tempBoard.robots, 0, robots, 0, tempBoard.robots.length); 
    this.size = tempBoard.size; 
    this.goal = tempBoard.goal; 
    this.moves = tempBoard.moves; 
}