Skip to content

Demystifying Stream Characteristics. A Key to Efficient Functional Code

Posted on:September 1, 2023 at 07:13 PM

Welcome back, eager learners! In our last lecture, we were delving deep into the world of Spliterator and exploring its various methods. Now, we’re going to unravel the secrets of stream characteristics. What are these characteristics, and how do they play a pivotal role in optimizing functional code? Let’s find out.

Table of contents

Open Table of contents

Sections

Spliterator Characteristics: Unveiling the Enigma

In the Spliterator interface, you’ll discover eight constants that serve as spliterator characteristics. These characteristics define the state of the stream they are associated with. They are implemented as plain integers and are used to signify different aspects of the stream. Let’s take a closer look at these characteristics:

ORDERED: This characteristic indicates that the order of elements in the stream matters. For instance, a stream generated from an ArrayList preserves the order of elements.

DISTINCT: The DISTINCT characteristic signals that there are no duplicate elements in the spliterator. This is common in sets or hash sets, where duplicates are not allowed.

SORTED: The SORTED characteristic signifies that the stream’s elements are sorted according to their natural order. This is applicable when creating a stream from a sorted set, for example.

SIZED: When a spliterator has the SIZED characteristic, it means that the size of the spliterator is known. You have an estimate of the number of elements.

NONNULL: The NONNULL characteristic guarantees that there are no null values present in the stream. It’s all about non-null safety.

IMMUTABLE: When a stream has the IMMUTABLE characteristic, it suggests that the stream is immutable. Once created, it won’t change.

CONCURRENT: The CONCURRENT characteristic indicates that the stream is built on a concurrent data structure. For example, a concurrent hash map would exhibit this characteristic.

SUBSIZED: Similar to SIZED, the SUBSIZED characteristic implies that the size is known, but it also signifies that all spliterators resulting from the trySplit method will also be sized when going parallel.

Detecting Characteristics: How to Know What’s Set

So, how can you check which characteristics are set for a particular spliterator? Well, it’s not as cryptic as it sounds. You can perform a bitwise OR operation on the constants and then count the bits. Here’s how you can do it:

int bits = spliterator.characteristics();
int count = Integer.bitCount(bits);

The ‘count’ will give you the number of characteristics set for that spliterator.

Don’t Duplicate: Handling Pre-Set Characteristics

If a characteristic is already set for a spliterator, performing a bitwise OR operation with the same characteristic won’t have any effect. For example, if ‘ORDERED’ is already set, performing an OR operation with ‘ORDERED’ won’t change the result.

Efficiently Checking for a Specific Characteristic

If you want to efficiently check whether a specific characteristic is set for a spliterator, you can use the hasCharacteristics(int characteristics) method. It returns true if the specified characteristic is set, making it a clean and straightforward way to check.

Now that you’ve cracked the code on stream characteristics and how they are determined, let’s explore how these characteristics play a vital role in optimizing your functional code. Buckle up, because this is where the magic happens!

You can find the repo for this section of the course Here