簡體   English   中英

使用Java創建異常的迭代器麻煩

[英]Iterator trouble using Java creating exceptions

String input from keyboard
Vector<String> myVector = new Vector<String>(someArray.length);   //assume Vector is populated
Iterator<String> itr = myVector.iterator();

for loop begins
    while(itr.hasNext() && itr.next().equals(input)){
       itr.remove();
    }

    ...

    while(itr.hasNext()    // is this the problem source?
     run more code  

for loop ends

當當前元素等於字符串input ,我想刪除該元素,否則繼續迭代。 我在這里不斷收到並發異常。

我還應該怎么辦? 我應該將itr.next移到其他地方嗎?

問題:我想要這樣的邏輯:如果當前Vector元素等於目標,我希望將其從Vector中刪除。 我怎樣才能做到這一點?

遍歷一個集合並且不仔細地從集合中刪除元素時,可能引發ConcurrentModificationException

我建議您構建一個單獨的List來包含要刪除的元素,並在循環執行完后將它們從原始Vector全部刪除。

其他建議:

您也可以遍歷列表的副本。

使用foreach循環:

for (String value : myVector) {
  ...
}

我不知道為什么會出現並發修改異常,因為通過迭代器刪除項是合法的:根據文檔,

如果在創建Iterator之后的任何時間對Vector進行結構修改, 除非通過Iterator自己的remove或add方法否則 Iterator將拋出ConcurrentModificationException

要回答有關從向量中刪除等於target的所有元素的問題,最簡單的解決方案是使用VectorremoveAll方法。

myVector.removeAll(Collections.singletonList(input));

您是否已初始化向量的內容? 您正在構造函數中設置它的長度,但是我看不到您實際上在向它添加字符串,這將導致NullPointerException。

您可能要使用以下方法初始化Vector:Arrays.asList(someArray)

當具有正確的Vector時,您無需在for循環中為迭代器設置while循環

這樣的事情應該起作用:

String[] someArray = new String[]{ "A", "B", "C" };
Vector<String> myVector = new Vector<String>(Arrays.asList(someArray));
Iterator<String> itr = myVector.iterator();
while(itr.hasNext()){
   String myString = itr.next();
   if (myString.equals(input)) itr.remove();
}

編輯出現異常的原因很可能是因為您錯誤地調用了.next方法。 .next方法僅應在每個hasNext調用之后調用一次,.remove僅應在每個.next調用之后調用一次。 由於您已省略了代碼中的詳細信息,因此很難准確地找出問題所在。 但總的來說,不需要for循環。 while循環應該足夠,但是if語句中不應該具有hasNext next

使用迭代器進行迭代的正確方法是(使用偽代碼):

while (iterator has more items) {
    get the next item
    do something with the item (remove it if it should be removed, or handle it in another way)
}

我只是避免整個迭代器。 這應該做您想要的:

  while (myVector.remove(input)) {
    // this should get them all
  }

嘗試像這樣包裝您的Vector:

Vector vector = Collections.synchronizedCollection(vector);

以及簡短的javadoc說明:

返回由指定集合支持的同步(線程安全)集合。 為了保證串行訪問,至關重要的是所有對后備集合的訪問都必須通過返回的集合來完成。

當用戶遍歷返回的集合時,必須手動對其進行同步:

Collection c =
 Collections.synchronizedCollection(myCollection);
      ...   synchronized(c) {
       Iterator i = c.iterator(); // Must be in the synchronized block
       while (i.hasNext())
          foo(i.next());   }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM