开发者

IndexOutOfBoundsException - only sometimes?

I keep getting random java.lang.IndexOutOfBoundsException errors on my program. What am i doing wrong? The program runs fine, its a really long for loop, but for some elements i seem to be getting that error and then it continues on to the next element and it works fine.

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);
}

How can i prevent this errors?


For those thinking this is an array, it is more likely a list.

Let me guess, you used to be getting ConcurrentModificationExceptions, so you rewrote the loop to use indexed lookup of elements (avoiding the iterator). Congratulations, you fixed the exception, but not the issue.

You are changing your List while this loop is running. Every now and then, you remove an element. Every now and then you look at the last element size()-1. When the order of operations looks like:

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

You access an element that no longer exists, and will raise an IndexOutOfBoundsException.

You need to fix the logic around this List by controlling access to it such that if you need to check all elements, you don't assume the list will be the same as it crosses all elements, or (the much better solution) freeze the list for the loop.

A simple way of doing the latter is to do a copy of the List (but not the list's elements) and iterate over the copy.

--- Edited as the problem dramatically changed in an edit after the above was written ---

You added a lot of extra code, including a few extra list lookups. You are using the same index for all the list lookups, but there is nothing to indicate that all of the lists are the same size.

Also, you probably don't want to skip across elements, odds are you really want to access all of the cabin classes in a segmentInfo, not just the 3rd cabinClass in the 3rd segmentInfo, etc.


You seem to be using i to index into two entirely separate List objects:

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

This looks wrong to me. Is this supposed to happen this way? And is the list returned by getCabinClass() guaranteed to be at least as long as the one returned by getSegmentInfo()?


You're using i both as an index for the list of segment infos and for the list of cabin classes. This smells like the source of your problem.

I don't know your domain model but I'd expect that we need two different counters here.


Refactored code to show problem (guessed the types, replace with correct class names)

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);
}


Assuming that response.getSegments().getSegmentInfo() always returns an array of the same size, calling .get(i) on it should be safe, given the loop header (but are you aware that you are skipping the last element?) However, are you sure that .getCabinSummary() will return an array that is as large as the getSegmentInfo() array? It looks suspicious that you are using i to perform lookups in two different arrays.

You could split the first line in the loop body into two separate lines (I'm only guessing the type names here):

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

Then you'll see which lookup causes the crash.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜