Hi,
On 05/09/2015 04:36 PM, Ivan Gerasimov wrote:
On 09.05.2015 14:15, Doug Lea wrote:
On 05/08/2015 02:17 PM, Ivan Gerasimov wrote:
The spec says "The returned list is backed by this list"
and "The subclass's set(int, E), get(int), add(int, E), remove(int),
addAll(int, Collection) and removeRange(int, int) methods all
delegate to the
corresponding methods on the backing abstract list".
It is possible that no differences could be detected, but it would
take
some effort to prove.
Hm. Let me try.
We have two options:
1) Sublist of an arbitrary AbstractList, which is not SubList itself.
2) Sublist of another SubList.
Plus:
3) An arbitrary wrapping of SubList, as seen for example in Collections
utilities like synchronizedList:
public List<E> subList(int fromIndex, int toIndex) {
synchronized (mutex) {
return new SynchronizedList<>(list.subList(fromIndex,
toIndex),
mutex);
}
}
... which can define methods relying on the specified full cascade.
Sorry, I cannot see how wrapping of SubList is different from any
other dealing with the sublist's API.
Shouldn't it remain as before, as long as we preserve the list's
behavior?
I think Ivan is right here and this is safe, because SubList and
RandomAccessSubList can not be overridden outside AbstractList. In a
chain of sub-lists, there can be runs of consecutive
[RandomAccess]SubList(s) intermingled with custom implementations that
can not be SubList subclasses:
SubList@1 -> SubList@2 -> CustomSubListA -> CustomSubListB -> SubList@3
-> SubList@4 -> ListImpl
It is guaranteed that SubList.root pointers in above scenario will be
(see SubList(AbstractList, ...) constructor):
[email protected] == CustomSubListA
[email protected] == CustomSubListA
[email protected] == ListImpl
[email protected] == ListImpl
In order for a sub-list to be skipped with add,get,... invocations, it
has to be a SubList (see SubList(SubList, ...) constructor). And there
can be not custom SubList subclasses.
So no invocation of any custom method can be skipped.
Regards, Peter