Quite a bit of code in the JDK uses Stream.collect(Collectors.toList()). This was introduced in JDK 8 and so there is fairly widespread use at this point. Stream.toList() was introduced in JDK 16. It should be faster in most cases, potentially avoiding reallocation and copying of arrays. However, Stream.toList() differs from Collectors.toList() in a couple different ways:
1. Stream.toList() returns an unmodifiable list, whereas the characteristics of the list returned by Collectors.toList() are mostly unspecified. In fact, it returns an ArrayList, and calling code might rely on that. If the calling code attempts to mutate such a list, it will "work" today but it will break if it's converted to Stream.toList().
2. If the returned list is serialized, the resulting bytes can't be deserialized on an older JDK, since the implementation class of lists returned by Stream.toList() don't exist on older JDKs.
3. Collectors.toList() has variance in the type parameter (actually provided by Stream.collect) whereas Stream.toList does not. This is mainly a source transformation issue, not a runtime issue.
However, many or most uses of Collectors.toList() are safe to be converted to Stream.toList(), and this can be verified safe via local reasoning. However, each change does need to be verified individually.
For these reasons, an _en masse_ conversion is inappropriate. Instead, the work should be broken into chunks and sub-tasks of this RFE should be created to cover chunks of code to be converted. One possible chunking boundary is module-by-module. But java.base is quite diverse, so it might need to be broken down further. Chunks of work should be chosen so as to minimize the number of reviewers for each chunk.
1. Stream.toList() returns an unmodifiable list, whereas the characteristics of the list returned by Collectors.toList() are mostly unspecified. In fact, it returns an ArrayList, and calling code might rely on that. If the calling code attempts to mutate such a list, it will "work" today but it will break if it's converted to Stream.toList().
2. If the returned list is serialized, the resulting bytes can't be deserialized on an older JDK, since the implementation class of lists returned by Stream.toList() don't exist on older JDKs.
3. Collectors.toList() has variance in the type parameter (actually provided by Stream.collect) whereas Stream.toList does not. This is mainly a source transformation issue, not a runtime issue.
However, many or most uses of Collectors.toList() are safe to be converted to Stream.toList(), and this can be verified safe via local reasoning. However, each change does need to be verified individually.
For these reasons, an _en masse_ conversion is inappropriate. Instead, the work should be broken into chunks and sub-tasks of this RFE should be created to cover chunks of code to be converted. One possible chunking boundary is module-by-module. But java.base is quite diverse, so it might need to be broken down further. Chunks of work should be chosen so as to minimize the number of reviewers for each chunk.
1.
|
convert jdeps and jdeprscan tools to use Stream.toList() |
|
Resolved | Ian Graves | |
2.
|
Convert jlink tool to use Stream.toList() |
|
Resolved | Ian Graves | |
3.
|
Convert javadoc tool to use Stream.toList() |
|
Resolved | Ian Graves | |
4.
|
Convert jshell tool to use Stream.toList() |
|
Resolved | Ian Graves | |
5.
|
Convert jpackage to use Stream.toList() |
|
Resolved | Ian Graves | |
6.
|
Convert jdk.compiler to use Stream.toList() |
|
Resolved | Ian Graves | |
7.
|
Convert java.base to use Stream.toList() |
|
Resolved | Ian Graves |