2016-02-13 121 views
-1

我有一個類稱爲單元並在它我有一個運行這段代碼的更新方法:如果語句忽略返回方法,其他解決方案?

if(goalReached){ 
    if(returnNearestCell() > -1 && isTarget && this.checkCollide(cells.get(returnNearestCell()).x, cells.get(returnNearestCell()).y, cells.get(returnNearestCell()).mass)){ 
    addMass(cells.get(returnNearestCell()).mass); 
    cells.get(returnNearestCell()).mass = 20; 
    cells.get(returnNearestCell()).x = (int) Math.floor(Math.random() * 1001); 
    cells.get(returnNearestCell()).y = (int) Math.floor(Math.random() * 701); 
    isTarget = false; 
    } 
    if(returnNearestCell() > -1 && !isTarget){ 
    goalX = cells.get(returnNearestCell()).x; 
    goalY = cells.get(returnNearestCell()).y; 
    target = cells.indexOf(returnNearestCell()); 
    isTarget = true; 

    }else if(returnNearestCell() == -1){ 
    goalX = (int) Math.floor(Math.random() * 1001); 
    goalY = (int) Math.floor(Math.random() * 701); 
    isTarget = false; 
    } 
    if(!isTarget){ 
    addMass(5); 
    } 
    goalReached = false; 
} 

基本上概括起來講,每個小區查找與一更小的質量,並且如果最近的細胞細胞,然後將goalX和goalY設置爲該細胞的位置。如果沒有發現具有相同標準的這樣的單元格,則只需轉到隨機位置。代碼工作正常,直到由於某種原因,第一個if語句被忽略:

returnNearestCell() > -1 

然後我得到一個ArrayIndexOutOfBoundsException。

我returnNearestCell方法進行如下:

public int returnNearestCell(){ 

int x = 0; 
int distance = 9999999; 
int min = distance; 

for(Cell cell : cells){ 
    if(this != cell){ 
    distance = (int)Math.sqrt((this.x - cell.x)*(this.x - cell.x) + (cell.y - this.y)*(cell.y - this.y)); 
    if(distance < min && this.mass > cell.mass + 10){ 
     min = distance; 
     x = cells.indexOf(cell); 
    }else if(distance < min && this.mass < cell.mass + 10 && cell.cellCount == cells.size()){ 
     x = -1; 
    } 
    } 
} 

return x; 
} 

此方法返回小區的索引與標準或-1。我的問題是:有什麼辦法可以避免這種OutofBoundsException?我已經嘗試了多種方法,例如重複檢查,但我仍然遇到同樣的問題。

+0

我建議你做適當的診斷工作,這樣你就可以縮小成一個[mcve]。考慮到你不明白的行爲(假設「忽略」if語句),我會試着首先解決這個問題。 –

+2

我也建議在你的方法中調用'returnNearestCell' *一次*,並在整個方法中使用該結果。你爲什麼要多次打電話?我可能實際上會讓它返回'Cell'(或者如果沒有找到,則返回null),而不是索引,它會使你的代碼變得更簡單,我懷疑... –

+1

它可以幫助知道它在什麼位置拋出異常 –

回答

1
cells.get(returnNearestCell()).mass = 20; 
cells.get(returnNearestCell()).x = (int) Math.floor(Math.random() * 1001); 
cells.get(returnNearestCell()).y = (int) Math.floor(Math.random() * 701); 

在這裏,您正在突變單元格,然後再次調用returnNearestCell()。由於該方法現在使用更改的參數運行,所以返回值可能不同。最重要的是,您沿着座標系移動單元格,然後在通過下一個returnNearestCell()調用進行評估時位於不同的位置。

您可能想查看非原子更新併發修改瞭解更多關於此主題的信息。

是否有任何方法將對象存儲到變量中並通過該變量訪問它?

是和它的解決問題的方法:

if (goalReached) { 
    // retrieve nearest cell once before modification 
    final int nearestCellIndex = returnNearestCell(); 
    if (nearestCellIndex > -1 && isTarget) { 
     // save cell. 
     final Cell nearestCell = cells.get(nearestCellIndex); 

     if (this.checkCollide(nearestCell.x, nearestCell.y, nearestCell.mass)) { 

      // remainder of your code 
     } 
    } 
} 

注意,它可能是最好有returnNearestCell()回報Optional<Cell>或至少Cell直接對象。 checkCollide()也是一樣,只需要一個Cell對象作爲參數。

+0

如果沒有找到單元格(如果我直接返回單元格),我的方法會返回什麼? – BruceTheGoose

+1

@BruceTheGoose如果返回類型是'Cell',你唯一的理智選擇是返回'null'。如果使用Java 8,您可能需要考慮使用['Optional'](https://docs.oracle。com/javase/8/docs/api/java/util/Optional.html)並返回'Optional.empty()'。 – dhke