2013-07-28 42 views
2

我在這裏是新的,所以我不確定是否可以在同一篇文章中有兩個問題,所以如果我不應該告訴我(很好!),我會改變它在這裏提出一個問題,並在別處開始另一篇文章字符串外觀相同但不匹配;列表迭代器異常

第一個問題:

下面就5-8行我指的是兩個字符串,我需要比較,看看他們是相同的。我使用getUserInput()方法來獲得終端用戶的響應,然後我繼續打印這兩個字符串,以便我可以直觀地檢查它們,並且它們也會一樣。但是,if節應該在運行時運行,但永遠不會運行,然後else節始終運行。

問題二:

else部分正下方,每當currentChump的健康被降低到< 1,我得到的,我從來沒見過,不知道什麼做的異常的塊關於。

這裏是我的代碼,然後在下面,我將粘貼例外:

for (Chump currentChump : chumpArray) { 
    System.out.println(" "); 
    String playerChoice = helper.getUserInput(
          "Type the name of the Weapon that you wish to use."); 
    System.out.println(playerChoice); 
    System.out.println(currentChump.getWeakness().toLowerCase()); 
    if (currentChump.getWeakness().toLowerCase() == playerChoice) { 
     chumpArray.remove(currentChump); 
    } // END IF 
    else { 
     while (PlayerIsAlive && currentChump.getHealth() > 0) { 
      int damage = (int) Math.floor((Math.random() * 6) + 1); 
      System.out.println(currentChump.getName() + " has " 
          + currentChump.getHealth() + "health remaining."); 
      currentChump.setHealth(currentChump.getHealth() - damage); 
      System.out.println("You hit the enemy for " 
          + damage + " points of damage."); 
      System.out.println(currentChump.getName() + " has " 
          + currentChump.getHealth() + " health remaining."); 
    System.out.println(" "); 
      if (currentChump.getHealth() < 1) { 
       chumpArray.remove(currentChump); 
      } // END IF 
      else { 
       int damage2 = (int) Math.floor((Math.random() * 4) + 1); 
       player.setHealth(player.getHealth() - damage2); 
       if (player.getHealth() < 1) { 
        PlayerIsAlive = false; 
       } // END IF 
      } // END WHILE 
     } // END ELSE 
    } // END ELSE 
} // END FOR 

例外:

Exception in thread "main" java.util.ConcurrentModificationException 
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) 
at java.util.AbstractList$Itr.next(AbstractList.java:343) 
at ArenaGameCopy.startPlaying(ArenaGameCopy.java:87) 
at ArenaGameCopy.main(ArenaGameCopy.java:168) 
+1

我很開心有人認爲我很棒。 :) –

+2

一般來說,你應該[單獨提出另外的問題](http://meta.stackexchange.com/q/39223/193053)。 – Jeffrey

+0

謝謝Jeffrey,我將來會這樣做的。 –

回答

7

使用Iterator循環之中,當你想從列表中刪除項目和使用Iterator.remove()而不是修改基礎列表。

報價JavaDoc

...這不是一般允許的,而另一個線程上進行迭代一個線程修改集合 。一般而言,在這些情況下迭代的結果是不確定的。如果檢測到此行爲,則某些迭代器(包括JRE提供的所有通用集合 實現中的那些)的實現可能會選擇拋出此異常 異常。這樣做的迭代器是 ,稱爲失敗快速迭代器,因爲它們快速且乾淨地失敗,相當 可能在將來未確定的 時間冒任意的非確定性行爲。

請注意,此例外情況並不總是表明某個對象已由另一個線程同時修改了 。如果單個線程 發出一系列方法調用違反對象的合約 ,該對象可能會拋出此異常。例如,如果 線程在使用快速迭代器迭代 集合時直接修改集合,那麼迭代器將拋出此異常。

注意,快速失敗行爲不能得到保證,因爲它是一般 來講,不可能作出任何硬性保證 不同步併發修改的存在。盡力而爲,快速失敗操作拋出 ConcurrentModificationException。因此, 在編寫依賴於此例外的程序時是錯誤的: 其正確性:ConcurrentModificationException應該僅使用 來檢測錯誤。


讓我來幫你。閱讀代碼中的註釋:

import java.util.*; 

/** 
    Hello! Welcome to basics. 
    This is what called a SSCCE. 
    Next time anyone asks for it, do it. 
    Because, 90% of the times, creating SSCCE will help you identify the issue. 
    Hope you learn something from these lines. 

    To compile and execute this code do the following: 
    a. Paste this class from import to last closed bracket in a 
    file named Test.java 
    b. javac Test.java 
    c. java Test 
    Bliss! 
*/ 
public class Test{ 

    public static void main(String[] args){ 
    // 1. Do not worry about these lines 
    // I am just creating some sample data 
    List<String> chumpArray = Arrays.asList("Oh my god! You must know to create SSCCE".split("\\s")); 
    chumpArray = new ArrayList<String>(chumpArray); 
    System.out.println("List to be iterated: " + chumpArray); 

    // 2. This is what I meant when I said to use an Iterator 
    // Obviously, your iterator will look like Iterator<Chump> 
    for(Iterator<String> chumpIt = chumpArray.iterator(); chumpIt.hasNext();) { 

     // 3. Materialize the current item 
     String currentChump = chumpIt.next(); 
     System.out.println("Currently on: " + currentChump); 

     // 3. String comparison 
     // ==   WRONG 
     // .equals  RIGHT 
     if (currentChump.toLowerCase().equals("you")) { 
      System.out.println("DELETING: " + currentChump); 
      // 4. Just ask the iterator to remove the current Item 
      chumpIt.remove(); 
      // Was it really so hard?! 
     } 
    } 
    System.out.println("List after delete: " + chumpArray); 
    } 
} 

在執行此操作,我們得到

tmp$ java Test 
List to be iterated: [Oh, my, god!, You, must, know, to, create, SSCCE] 
Currently on: Oh 
Currently on: my 
Currently on: god! 
Currently on: You 
DELETING: You 
Currently on: must 
Currently on: know 
Currently on: to 
Currently on: create 
Currently on: SSCCE 
List after delete: [Oh, my, god!, must, know, to, create, SSCCE] 

HTH
NISHANT

+0

是否有人會教我如何使用Iterator來修改該代碼?我以前從來沒有用過,現在我一直在看它,但我並不真正瞭解它。我肯定會在我的工具包中有一個新的工具!感謝大家的幫助! –

+0

請提供一個[SSCCE](http://sscce.org),我會幫你作爲星期天外賣:) – Nishant

+0

謝謝,Nishant。現在我要開始研究這是什麼了! –

7

你不能使用==比較字符串作爲==將比較的對象...不是字符串的值

if (currentChump.getWeakness().toLowerCase() == playerChoice)

應該

if (currentChump.getWeakness().toLowerCase().equals(playerChoice)) 

if (currentChump.getWeakness().equalsIgnoreCase(playerChoice)) 

第二個問題似乎您試圖修改一個對象(列表)是另一個線程的一部分。

+0

第二個問題是錯誤的。它根本不是多線程的。它將從列表中刪除一個項目,同時迭代它。 '(Chump currentChump:chumpArray)'語句在引擎蓋下創建一個'Iterator'。 –

4

第一個問題

比較字符串時總是使用equals

運算符==的作用是檢查對象是否相同。

這似乎與字符串一起工作的唯一原因是因爲interning

這意味着,除非已明確使用了String構造函數,否則具有相同字符序列的引用指向同一個String對象。這應該是爲了減少內存使用量。

問題二

Exception in thread "main" java.util.ConcurrentModificationException 

這是通過使用增強的for循環修改你迭代的結構造成的。

link解釋了爲什麼拋出異常。

在迭代的每個next()方法調用,

final void checkForComodification() { 
     if (modCount != expectedModCount) 
    throw new ConcurrentModificationException(); 
    } 

方法被調用,以檢查是否有列表是由機會。 如果它們不匹配 ,將拋出ConcurrentModificationException。

補充意見

對於您似乎已經部分地尊重你可以在你的布爾變量命名從PlayerIsAliveisPlayerAlive公約的緣故。這是camelCase中的第一個小數,「is」用於立即向讀者指出它是真/假值。