Skip to content

Make Lists.transform() delegate spliterator() to the backing list. - #8644

Open
Divyansh151005 wants to merge 1 commit into
google:masterfrom
Divyansh151005:fix/lists-transform-spliterator
Open

Make Lists.transform() delegate spliterator() to the backing list.#8644
Divyansh151005 wants to merge 1 commit into
google:masterfrom
Divyansh151005:fix/lists-transform-spliterator

Conversation

@Divyansh151005

@Divyansh151005 Divyansh151005 commented Aug 30, 2026

Copy link
Copy Markdown

Problem

Lists.transform() list views did not override spliterator(). They inherited AbstractList/AbstractSequentialList spliterators that iterate via indexed access or list iterators on the transformed view. For backing lists with special spliterator behavior (notably CopyOnWriteArrayList, whose spliterator snapshots the array), streaming over the transformed view could throw ConcurrentModificationException while the backing list was being modified concurrently.

Example from the issue:

var cow = new CopyOnWriteArrayList<Integer>();
// ... concurrent adds/clears in another thread ...
Lists.transform(cow, s -> s).stream().forEach(x -> {}); // CME

Fixes #8165

Solution

Override spliterator() on both TransformingRandomAccessList and TransformingSequentialList to delegate through CollectSpliterators.map(fromList.spliterator(), …), matching Collections2.transform and Iterables.transform.

Testing

$ export JAVA_HOME=~/.m2/jdks/jdk-26.0.2+10/Contents/Home
$ ./mvnw -B -Dtoolchain.skip test -Dmaven.javadoc.skip=true \
    -Dsurefire.toolchain.version=17 \
    '-Dtest=com.google.common.collect.ListsTest#testTransformSpliterator*' \
    -DfailIfNoTests=false -pl guava-tests -am

[INFO] Tests run: 6002, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS

New tests verify characteristic delegation for random-access and sequential transforms, and that streaming over Lists.transform(copyOnWriteArrayList, …) does not throw while the backing list is mutated concurrently.

Fixes google#8165

RELNOTES=`collect`: Fixed `Lists.transform()` to delegate `spliterator()` to the backing list so characteristics such as `IMMUTABLE` are preserved and streaming over a concurrently modified list (for example `CopyOnWriteArrayList`) no longer throws `ConcurrentModificationException`.

Co-authored-by: Cursor <cursoragent@cursor.com>
@google-cla

google-cla Bot commented Aug 30, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lists::transform and probably others do not produce spliterators/iterators with correct characteristics

1 participant