> --
> guava-...@googlegroups.com.
> http://groups.google.com/group/guava-discuss?hl=en
> unsubscribe: guava-discus...@googlegroups.com
>
> This list is for discussion; for help, post to Stack Overflow instead:
> http://stackoverflow.com/questions/ask
> Use the tag "guava".
>
--
I suggest catching the exception thrown from set(), but not revert to the iterator solution - we know this is a RandomAccess list, so the optimization *is* important. So accumulate the unfiltered elements to another buffer, and in the end clear() the list and addAll() the elements back to it. Less than ideal due to the exception, surely, and one can't play tricks by removing the stack trace of that to make it faster, because it is important for debugging other cases.
I suggest catching the exception thrown from set(), but not revert to the iterator solution - we know this is a RandomAccess list, so the optimization *is* important. So accumulate the unfiltered elements to another buffer, and in the end clear() the list and addAll() the elements back to it. Less than ideal due to the exception, surely, and one can't play tricks by removing the stack trace of that to make it faster, because it is important for debugging other cases.
It is an interesting issue though in itself. Perhaps there is something more to be learned here, regarding proxying/decorator designs generally.
Ideally, all that would be needed to cleanly solve this would be a copy(int from, int to) method, which can be implemented by TransformingRandomAccessList. (Say, in a package-private interface). Alas, while this would "fix" nested transforming lists, it would quickly break if view of another kind was intercepted, e.g. Collections.synchronizedList(Lists.transform(...)), unless this other view took the measures to preserve this extra interface. Look for example a synchronized List view tries not to lose the "RandomAccess"ness of the wrapped list:
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<T>(list) :
new SynchronizedList<T>(list));
}
This clearly cannot scale in face of other interfaces advertizing capabilities in a List. This also reminds me the case where you are given an InputStream, and you cannot tell whether it is buffered or not. You could easily do an instanceof, but if it is wrapped, this capability is hidden, so one can end up with multiple, redundant buffers in a chain. In that case, a method "isBuffered()" would suffice, and it could easily be propagated in decorators, but then we would have an unbounded collection of methods. Perhaps the language is too restrictive to effectively tackle these cases.