2013-10-09 56 views
0

好吧,我正在寫多米諾骨牌般的程序,我在其中添加,移除,旋轉瓷磚以將它們放置在棋盤上等等。也許我錯過了一些基本上簡單的東西,但我不能爲我的生活找出爲什麼當我試圖從董事會中刪除一塊瓷磚,我得到一個IndexOUtOfBoundsException。我已經手動追蹤了代碼,使用了以前從未使用過的調試工具,並且所有的值都是正確的。ArrayList IndexOutOfBoundsException Java

以下是我使用的瓷磚添加到板的方法之一:

public boolean placePieceAfter(int tile[]) 
{ 
    if (tile[1] == Board.board.get(Board.board.size() - 1)) 
    { 
     for (int index = 0; index < 4; index = index + 1) 
      Board.board.add(tile[index]); 
     return true; 
    } 
    else 
    { 
     System.out.println("\n" + red + "You cannot place this piece last."); 
     return false; 
    } 
} 

以下是我使用的是看我可以插入一個給定的play()方法從玩家/計算機手中的瓦片(在前面,或者在匹配的瓦片之間或之後)插入板中。我假設當我引用if語句中的方法時,它們被執行(我是否正確?)。我還放置了System.out.println語句來查看我正在使用的變量的值。

public boolean play()  
{ 
    int firstElement = 0; 
    int secondElement = 0; 
    int thirdElement = 0; 
    int fourthElement = 0; 

    for (int checkEveryTile = 0; checkEveryTile < computerHand.size(); checkEveryTile = checkEveryTile + 4) 
    { 
     computerHand.size(); 
     System.out.println("Computer hand: " + computerHand); 

     for (int elementInEachTile = checkEveryTile; elementInEachTile < (elementInEachTile + 4); elementInEachTile = elementInEachTile + 1) 
     { 
      boolean gatheredElements = false; 
      while (!gatheredElements) 
      { 
       firstElement = computerHand.get(elementInEachTile); 
       secondElement = computerHand.get(elementInEachTile + 1); 
       thirdElement = computerHand.get(elementInEachTile + 2); 
       fourthElement = computerHand.get(elementInEachTile + 3); 
       gatheredElements = true; 
      } 
      int tileToTestFor[] = {firstElement, secondElement, thirdElement, fourthElement}; 

//    int elementToAddToTile = computerHand.get(index);  
//elementToAddToTile = first element in computerHand 

//    for (int addingToTileToTestFor = 0; addingToTileToTestFor < 4; addingToTileToTestFor = addingToTileToTestFor + 1) 
//     tileToTestFor[addingToTileToTestFor] = elementToAddToTile;  
//tileToTest for gets first element of computerHand 

      if (placePieceBefore(tileToTestFor)) 
      { 
       System.out.println("Location of checkEveryTile (Index): " + checkEveryTile); 
       System.out.println("Element at checkEveryTile: " + computerHand.get(checkEveryTile)); 
       for (int indexToRemoveFrom = elementInEachTile; indexToRemoveFrom < (indexToRemoveFrom + 4); indexToRemoveFrom = indexToRemoveFrom + 1) 
        computerHand.remove(checkEveryTile); 
       Board.printBoard(); 
       return true; 
      } 

      else if (placePieceBetween(tileToTestFor)) 
      { 
       System.out.println("Location of checkEveryTile (Index): " + checkEveryTile); 
       System.out.println("Element at checkEveryTile: " + computerHand.get(checkEveryTile)); 
       for (int indexToRemoveFrom = elementInEachTile; indexToRemoveFrom < (indexToRemoveFrom + 4); indexToRemoveFrom = indexToRemoveFrom + 1) 
        computerHand.remove(checkEveryTile); 
       Board.printBoard(); 
       return true; 
      } 
      else if (placePieceAfter(tileToTestFor)) 
      { 
       System.out.println("Location of checkEveryTile (Index): " + checkEveryTile); 
       System.out.println("Element at checkEveryTile: " + computerHand.get(checkEveryTile));     
       for (int indexToRemoveFrom = elementInEachTile; indexToRemoveFrom < (indexToRemoveFrom + 4); indexToRemoveFrom = indexToRemoveFrom + 1) 
        computerHand.remove(checkEveryTile); 
       Board.printBoard(); 
       return true; 
      } 
      else 
       break; 
     } 
    } 
    System.out.println("\n" + red + "Computer could not play."); 
    return false; 
} 

這裏與我得到錯誤的輸出(它總是在playerHand.remove(checkEveryTile)computerHand.remove(checkEveryTile)語句的if語句內):

Pile before players get their respective hands. 
Pile: [5, 6, 7, 8, 0, 9, 4, 2, 2, 1, 4, 7, 9, 9, 5, 5, 7, 0, 3, 6, 4, 8, 2, 3, 4, 4, 2, 3, 5, 4, 1, 8, 9, 9, 0, 7, 4, 6, 6, 3, 2, 8, 6, 5, 0, 0, 1, 8, 8, 6, 0, 4, 6, 2, 7, 8, 9, 6, 7, 4, 0, 6, 9, 2, 6, 8, 2, 3, 3, 4, 8, 5, 3, 0, 7, 5, 4, 4, 9, 3, 6, 5, 0, 4, 3, 4, 1, 9, 1, 8, 6, 1, 7, 4, 2, 0, 6, 2, 2, 7, 8, 8, 7, 0, 5, 0, 8, 1, 6, 9, 3, 2, 6, 1, 0, 0, 5, 8, 0, 9, 3, 0, 1, 6, 7, 1, 4, 6, 0, 6, 3, 5, 0, 4, 6, 1, 0, 5, 8, 2, 6, 0, 7, 1, 3, 9, 5, 2, 3, 4, 7, 0, 5, 8, 3, 1, 3, 1, 0, 6, 3, 4, 3, 9, 6, 5, 5, 7, 2, 3, 4, 5, 9, 1, 0, 5, 1, 8, 4, 6, 5, 7, 2, 2, 1, 5, 0, 0, 0, 3, 1, 9, 1, 5, 4, 6, 0, 2, 8, 5, 2, 8, 2, 4, 0, 8, 8, 4] 

This is the player hand. 
Player hand: [5, 6, 7, 8, 0, 9, 4, 2, 2, 1, 4, 7, 9, 9, 5, 5, 7, 0, 3, 6] 

This is the computer hand. 
Computer hand: [4, 8, 2, 3, 4, 4, 2, 3, 5, 4, 1, 8, 9, 9, 0, 7, 4, 6, 6, 3] 

Pile after players get their respective hands. 
Pile: [2, 8, 6, 5, 0, 0, 1, 8, 8, 6, 0, 4, 6, 2, 7, 8, 9, 6, 7, 4, 0, 6, 9, 2, 6, 8, 2, 3, 3, 4, 8, 5, 3, 0, 7, 5, 4, 4, 9, 3, 6, 5, 0, 4, 3, 4, 1, 9, 1, 8, 6, 1, 7, 4, 2, 0, 6, 2, 2, 7, 8, 8, 7, 0, 5, 0, 8, 1, 6, 9, 3, 2, 6, 1, 0, 0, 5, 8, 0, 9, 3, 0, 1, 6, 7, 1, 4, 6, 0, 6, 3, 5, 0, 4, 6, 1, 0, 5, 8, 2, 6, 0, 7, 1, 3, 9, 5, 2, 3, 4, 7, 0, 5, 8, 3, 1, 3, 1, 0, 6, 3, 4, 3, 9, 6, 5, 5, 7, 2, 3, 4, 5, 9, 1, 0, 5, 1, 8, 4, 6, 5, 7, 2, 2, 1, 5, 0, 0, 0, 3, 1, 9, 1, 5, 4, 6, 0, 2, 8, 5, 2, 8, 2, 4, 0, 8, 8, 4] 

Board before anyone places a piece. 
Board: [] 
Board: [5] 
Board: [5, 6] 
Board: [5, 6, 7] 
Board: [5, 6, 7, 8] 
Player placed initial tile. 
Computer hand: [4, 8, 2, 3, 4, 4, 2, 3, 5, 4, 1, 8, 9, 9, 0, 7, 4, 6, 6, 3] 
Piece: [4, 8, 2, 3] 

You cannot place this piece in the beginning. 

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 
You cannot place this piece in the middle. 
Location of checkEveryTile (Index): 0 
Element at checkEveryTile: 4 
    at java.util.ArrayList.rangeCheck(ArrayList.java:604) 
    at java.util.ArrayList.remove(ArrayList.java:445) 
    at numbertiles.Computer.play(Computer.java:172) 
    at numbertiles.Board.takeTurns(Board.java:85) 
    at numbertiles.NumberTiles.main(NumberTiles.java:45) 
Java Result: 1 
BUILD SUCCESSFUL (total time: 0 seconds) 

這個問題的任何幫助,一定會理解。謝謝。

+3

這是很多需要經歷的代碼。將其縮小到與您的錯誤相關的部分。 – Prateek

+0

根據堆棧跟蹤,錯誤發生在Computer.java第172行。在那裏設置一個斷點,並確保沒有刪除超出'ArrayList'範圍的索引。 –

+0

在此處發佈任何內容之前_please_在調試器中逐句通過代碼。 99%的時間會以這種方式發現錯誤。如果您仍有問題,請將其降至最低[SSCCE](http://sscce.org)。 –

回答

0

這聽起來很愚蠢,但是如果您在通過獲取該id遍歷相同列表的同時通過增強循環刪除某個項目,則會出現此問題。嘗試使用迭代器邏輯(用於執行刪除邏輯的函數),而不是增強for循環。當你從迭代器中刪除時它工作正常。

Iterator itr = mylist.iterator(); 
while (itr.hasNext()){ 
if(itr.getItem().getId ==(ifInt)/.equals(indexId)}{ 
    { 
    itr.remove(); 
    } 
} 

希望這個工程。

+0

我認爲增強型for-loop的形式是:for(int index:list){// statements ...}但無論如何,這似乎是一個更簡單的解決方案,並會盡快嘗試。非常感謝。當我得到它的工作時會回覆你。 – rsant023

4

當你看到這

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 

你馬上就知道你是在處理一個空數組列表。另外異常下降跟蹤你看到例外發生在remove方法的調用:

at java.util.ArrayList.remove(ArrayList.java:445) 

這將導致您的罪魁禍首:在刪除您引用了錯誤的循環變量的所有瓷磚的循環:

for (int indexToRemoveFrom = elementInEachTile; indexToRemoveFrom < (indexToRemoveFrom + 4); indexToRemoveFrom = indexToRemoveFrom + 1) 
    computerHand.remove(checkEveryTile); <<== Here 

您在沒有檢查電腦指針有任何要移除的情況下調用remove(index),這會導致異常。

注:Java提供了寫作之類的東西

indexToRemoveFrom = indexToRemoveFrom + 1 

一個非常方便快捷,您可以用indexToRemoveFrom++更換爲更短,更易於閱讀的解決方案。

+0

謝謝你的回答。我只是檢查是否有任何一隻手是空的,這樣我就可以做.remove(checkEveryTile),它們最初的尺寸都是20。當我放置NativeTile()時,其中一個大小爲20,另一個大小爲16.因此,對於沒有玩過(20號大小)的玩家,我從我的代碼中瞭解到,我正在檢查EveryTile(每隔四個元素)並看看他們是否可以放置(如果陳述)。當我做.remove(checkEveryTile)時,我抓取了4的倍數並在該索引處移除了4次。我不明白爲什麼我不能在checkEveryTile中刪除。 :( – rsant023

+0

@ rsant023在'remove'之前添加'if'語句以檢查您要刪除的列表是否爲空將幫助您避免崩潰。在'else'分支中添加print語句可以幫助您理解碰撞發生在什麼條件下? – dasblinkenlight

相關問題