Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Stream#toList's default implementation seem overcomplicated / suboptimal?

Looking at the implementation for Stream#toList, I just noticed how overcomplicated and suboptimal it seemed.

Like mentioned in the javadoc just above, this default implementation is not used by most Stream implementation, however, it could have been otherwise in my opinion.

The sources

/**
 * Accumulates the elements of this stream into a {@code List}. The elements in
 * the list will be in this stream's encounter order, if one exists. The returned List
 * is unmodifiable; calls to any mutator method will always cause
 * {@code UnsupportedOperationException} to be thrown. There are no
 * guarantees on the implementation type or serializability of the returned List.
 *
 * <p>The returned instance may be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
 * Callers should make no assumptions about the identity of the returned instances.
 * Identity-sensitive operations on these instances (reference equality ({@code ==}),
 * identity hash code, and synchronization) are unreliable and should be avoided.
 *
 * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
 *
 * @apiNote If more control over the returned object is required, use
 * {@link Collectors#toCollection(Supplier)}.
 *
 * @implSpec The implementation in this interface returns a List produced as if by the following:
 * <pre>{@code
 * Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray())))
 * }</pre>
 *
 * @implNote Most instances of Stream will override this method and provide an implementation
 * that is highly optimized compared to the implementation in this interface.
 *
 * @return a List containing the stream elements
 *
 * @since 16
 */
@SuppressWarnings("unchecked")
default List<T> toList() {
    return (List<T>) Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray())));
}

My idea of what would be better

return (List<T>) Collections.unmodifiableList(Arrays.asList(this.toArray()));

Or even

return Arrays.asList(this.toArray()));

IntelliJ's proposal

return (List<T>) List.of(this.toArray());

Is there any good reason for the implementation in the JDK sources?

like image 356
Yassin Hajaj Avatar asked Apr 04 '21 21:04

Yassin Hajaj


People also ask

Why do we stream?

Streaming is a method of viewing video or listening to audio content without actually downloading the media files. Streaming performance can be improved, and buffering time reduced, if the owner of the files uses a CDN. What is streaming?

What does it mean when you stream?

What is streaming? Streaming refers to any media content – live or recorded – delivered to computers and mobile devices via the internet and played back in real time. Podcasts, webcasts, movies, TV shows and music videos are common forms of streaming content.

How does internet streaming work?

A streaming service for TV is the digital distribution of television content, usually TV shows, over the internet. The video content is then played on user devices as streaming media. Ever since the launch of YouTube and Netflix, there's been a substantial increase in the use of streaming web television.

Why do they call it streaming?

The term "streaming" was first used for tape drives manufactured by Data Electronics Inc. that were meant to slowly ramp up and run for the entire track; slower ramp times lowered drive costs. "Streaming" was applied in the early 1990s as a better description for video on demand and later live video on IP networks.

Why does my live stream keep buffering?

If the bitrate of the live stream exceeds the maximum speed of the internet connection, then it will likely cause buffering issues. 4. If the stream has multiple video qualities, select the lowest one. By selecting the lowest video quality it will reduce the amount of bandwidth required to view the video.

What is Microsoft Stream and how does it work?

Microsoft Stream supports Microsoft Edge and the current versions of Chrome and Safari. What is an encoder? Simply put, an encoder compresses audio and video from various inputs and sends that output to a streaming service, such as Microsoft Stream. Typically, there are hardware, software and mobile apps that you can use.

Why can’t I stream on Twitch?

It might be that your Internet connection is too slow and doesn’t have enough bandwidth for streaming from Twitch, or that the connection is flaky and experiencing excessive “ packet loss .”

Why is my streaming video quality so bad?

With streaming video, you must account for internet speed, Wi-Fi connectivity, the capabilities of your streaming device, and your individual streaming services, which have their own unique set of reliability issues. All of this makes troubleshooting more complicated if you run into problems such as buffering or poor video quality.


1 Answers

The toArray method might be implemented to return an array that is then mutated afterwards, which would effectively make the returned list not immutable. That's why an explicit copy by creating a new ArrayList is done.

It's essentially a defensive copy.

This was also discussed during the review of this API, where Stuart Marks writes:

As written it's true that the default implementation does perform apparently redundant copies, but we can't be assured that toArray() actually returns a freshly created array. Thus, we wrap it using Arrays.asList and then copy it using the ArrayList constructor. This is unfortunate but necessary to avoid situations where someone could hold a reference to the internal array of a List, allowing modification of a List that's supposed to be unmodifiable.

like image 147
Jorn Vernee Avatar answered Nov 02 '22 23:11

Jorn Vernee