簡體   English   中英

IndexOutOfBoundsException - 只是有時?

[英]IndexOutOfBoundsException - only sometimes?

我的程序中不斷出現隨機 java.lang.IndexOutOfBoundsException 錯誤。 我究竟做錯了什么? 該程序運行良好,它的 for 循環非常長,但對於某些元素,我似乎遇到了該錯誤,然后它繼續到下一個元素並且它工作正常。

for (int i = 0; i < response.getSegments().getSegmentInfo().size()-1; i++) {
   reservedSeats = response.getSegments().getSegmentInfo().get(i).getCabinSummary().getCabinClass().get(i).getAmountOfResSeat();
   usedSeats = response.getSegments().getSegmentInfo().get(i).getCabinSummary().getCabinClass().get(i).getAmountOfUsedSeat();
   System.out.println("Reserved Seats: " + reservedSeats);
   System.out.println("Used Seats    : " + usedSeats);
}

我怎樣才能防止這個錯誤?

對於那些認為這是一個數組的人來說,它更有可能是一個列表。

讓我猜猜,你曾經得到 ConcurrentModificationExceptions,所以你重寫了循環以使用元素的索引查找(避免迭代器)。 恭喜,您修復了異常,但沒有解決問題。

在此循環運行時,您正在更改您的列表。 時不時地,您刪除一個元素。 時不時地查看最后一個元素size()-1 當操作順序如下所示:

 (some thread)
 remove an element from response.getSegments().getSegmentInfo()
 (some possibly other thread)
 lookup up the size()-1 element of the above

您訪問一個不再存在的元素,並將引發 IndexOutOfBoundsException。

您需要通過控制對它的訪問來修復此列表的邏輯,以便如果您需要檢查所有元素,您不要假設列表與所有元素相同,或者(更好的解決方案)凍結循環列表。

執行后者的一種簡單方法是復制 List(但不是列表的元素)並遍歷該副本。

---在編寫上述內容后,由於問題在編輯中發生了巨大變化而進行了編輯---

您添加了很多額外的代碼,包括一些額外的列表查找。 您對所有列表查找使用相同的索引,但沒有任何跡象表明所有列表的大小相同。

此外,您可能不想跳過元素,很可能您真的想訪問段信息中的所有客艙類,而不僅僅是第 3 段信息中的第 3 客艙類等。

您似乎正在使用i來索引兩個完全獨立的List對象:

response.getSegments().getSegmentInfo().get(i) // indexing into response.getSegments().getSegmentInfo()
.getCabinSummary().getCabinClass().get(i) // indexing into getCabinSummary().getCabinClass()
.getAmountOfResSeat();

這在我看來是錯誤的。 應該以這種方式發生嗎? getCabinClass()返回的列表是否保證至少getSegmentInfo() () 返回的列表一樣長?

您將i用作分段信息列表和客艙等級列表的索引。 這聞起來像是問題的根源。

我不知道您的域 model 但我希望我們需要兩個不同的計數器。


重構代碼以顯示問題(猜測類型,替換為正確的 class 名稱)

List<SegmentInfo> segmentInfos = response.getSegments().getSegmentInfo();

for (int i = 0; i < segmentInfos.size()-1; i++) {
   // use i to get actual segmentInfo
   SegmentInfo segmentInfo = segmentInfos.get(i);
   List<CabinClass> cabinClasses = segmentInfo.getCabinSummary.getCabinClass();

   // use i again to get actual cabin class ???
   CabinClass cabinClass = cabinClasses.get(i);

   reservedSeats = cabinClass.getAmountOfResSeat();
   usedSeats = cabinClass.getAmountOfUsedSeat();

   System.out.println("Reserved Seats: " + reservedSeats);
   System.out.println("Used Seats    : " + usedSeats);
}

假設response.getSegments().getSegmentInfo()總是返回一個相同大小的數組,調用.get(i)應該是安全的,給定循環 header (但你知道你正在跳過最后一個元素嗎?)但是,您確定.getCabinSummary()將返回一個與getSegmentInfo()數組一樣大的數組嗎? 您使用i在兩個不同的 arrays 中執行查找看起來很可疑。

您可以將循環體中的第一行分成兩行(我只是在這里猜測類型名稱):

List<SegmentInfo> segmentInfo = response.getSegments().getSegmentInfo().get(i);
reservedSeats = segmentInfo.getCabinSummary().get(i).getAmountOfResSeat();

然后你會看到哪個查找導致崩潰。

暫無
暫無

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

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