RFR: 8079136: Accessing a nested sublist leads to StackOverflowError (original) (raw)

Ivan Gerasimov ivan.gerasimov at oracle.com
Wed May 6 03:51:51 UTC 2015


Thanks Louis for looking at this!

Removing an element from a sub-sublist is done as: 549 public E remove(int index) { 550 rangeCheck(index); 551 checkForComodification(); 552 E result = AbstractList.this.remove(index + offset); 553 updateSizeAndModCount(-1, AbstractList.this.modCount); 554 return result; 555 }

It first removes the element from the root list at the line 552. Then, it updates sizes of all sublist in the chain at 553, so that sizes of sublist and sub-sublist are decreased by one.

Sincerely yours, Ivan

On 06.05.2015 1:02, Louis Wasserman wrote:

Just checking -- IIRC, this will change the semantics of how structural modifications to a subList of a subList will affect the first subList. For example, I believe in the past, removing an element from a subList of a subList would decrease the size of the first subList by 1, but now the first subList will represent the same range of indices, and another element will be moved into that subList.

Is that an accurate representation of current behavior? Is changing that behavior acceptable in this context? On Tue, May 5, 2015 at 11:02 AM Ivan Gerasimov <ivan.gerasimov at oracle.com <mailto:ivan.gerasimov at oracle.com>> wrote: Hi Paul On 05.05.2015 19:56, Paul Sandoz wrote: > Hi Ivan, > > ArrayList > -- > > You can simplify SubList with: > > private final class SubList extends AbstractList implements RandomAccess { > private final SubList parent; > private final int offset; > int size; > > // Top level sub-list > SubList(int offset, int fromIndex, int toIndex) { > this.parent = null; > this.offset = offset + fromIndex; > this.size = toIndex - fromIndex; > this.modCount = ArrayList.this.modCount; > } > > // Sub sub-lst > SubList(SubList parent, > int offset, int fromIndex, int toIndex) { > this.parent = parent; > this.offset = offset + fromIndex; > this.size = toIndex - fromIndex; > this.modCount = ArrayList.this.modCount; > } > > ArrayList.subList becomes: > > public List subList(int fromIndex, int toIndex) { > subListRangeCheck(fromIndex, toIndex, size); > return new SubList(0, fromIndex, toIndex); > } > > And SubList.subList: > > public List subList(int fromIndex, int toIndex) { > subListRangeCheck(fromIndex, toIndex, size); > return new SubList(this, offset, fromIndex, toIndex); > } > > And SubList. updateSizeAndModCount: > > private void updateSizeAndModCount(int sizeChange) { > int modCount = ArrayList.this.modCount; > for (SubList slist = this; slist != null; slist = slist.parent) { > slist.size += sizeChange; > slist.modCount = modCount; > } > } > Thanks for suggestion! I should have realized this myself, that there's no need to set parent to ArrayList.this. It was a left-over from the previous design, when parent was used in different ways. > AbstractList > -- > > Similar changes can be made as above to ArrayList.SubList etc. > > The construction of sub-lists does indeed require a second take. A comment is worthwhile. IMO such scoping is not necessary for ArrayList, i have actually found it rare to require such scoping so using it when not necessary is rather jarring. > Okay, I'll reorganize it to make SubList classes stand-alone, not inner classes. Let's see, if it makes the things nicer. > NestedSubList > -- > > My preference is you use a testng data provider so you don't have to roll your own failure checking and reporting. > Are there any other tests for testing the integrity of sublists? I found only a few tests that test some parts of the functionality: test/java/util/List/LockStep.java test/java/util/Collection/MOAT.java

I'll post an update on the code and test soon. Sincerely yours, Ivan



More information about the core-libs-dev mailing list