You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/blog/java-streams.md
+24-3Lines changed: 24 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,6 +27,7 @@ Immutability ensures that the original data stays the same during stream operati
27
27
-**Thread Safety:** In places with lots of things happening at once (multi-threaded), immutability acts like a safety net. Many threads can use the original data at the same time without causing problems.
System.out.println("The above two lists are equal? "+ (mappedValues.count() == values.size()));
43
44
```
45
+
44
46
**Analysis:**
47
+
45
48
- The starting list stays the same; nothing is changed, proving that streams keep things unchanged.
46
49
- When we filter and map, it's like making a fresh stream, leaving the original data intact.
47
50
- Using `toList()` helps make a new list without messing up anything. It's like a safety feature for threads.
48
51
49
52
**Benchmark Output:**
53
+
50
54
```
51
55
Original List: [1, 10, 3, 4, 2]
52
56
Modified List: [11, 5]
@@ -59,10 +63,12 @@ Lists Equality: true
59
63
Streams, once consumed, cannot be reused. This design ensures that each stream operation, especially terminal operations, represents a distinct processing step. Once a terminal operation is invoked on a stream, it marks the end of its usability for further operations.
60
64
61
65
**How it Benefits:**
66
+
62
67
-**Efficient Resource Management:** When you have a large amount of data, utilizing streams in Java aligns with the practice of processing data and closing resources promptly. This practice helps prevent data leakage and minimizes the presence of unused resources.
63
68
-**Prevention of Unintended Behavior:** The inability to reuse streams after terminal operations minimizes the risk of unintended side effects, promoting safer and more controlled data manipulation. Attempting to use a consumed stream again results in an `IllegalStateException`, ensuring a clear and intentional data processing flow.
64
69
65
70
**Code Snippet and Benchmark Output:**
71
+
66
72
```java
67
73
// Creating a stream from the list
68
74
Stream<Integer> mappedValues = list.stream()
@@ -80,14 +86,17 @@ try {
80
86
System.out.println("Error: "+ e.getMessage());
81
87
}
82
88
```
89
+
83
90
**Analysis:**
91
+
84
92
- The code begins by creating a stream, `mappedValues`, from the original list.
85
93
- The stream is processed with an intermediate operation (`filter` and `map`) and a terminal operation (`count`).
86
94
- Attempting to reuse the `mappedValues` stream (here with `toList()`) after the terminal operation will result in an `IllegalStateException`. This error occurs because once a stream is consumed by a terminal operation, it cannot be reused for another terminal operation.
87
95
- The use of `count()` serves as a point of consumption, making the stream no longer available for further terminal operations.
88
96
89
97
**Output:**
90
-
```
98
+
99
+
```shell
91
100
Error: stream has already been operated upon or closed
92
101
```
93
102
@@ -97,10 +106,12 @@ Error: stream has already been operated upon or closed
97
106
Parallel streams divide the workload among multiple threads, leveraging the power of multicore processors for concurrent execution. They are designed for efficient processing of large datasets.
98
107
99
108
**How it Benefits:**
109
+
100
110
-**Reduced Execution Time:** Parallel processing leads to shorter execution times compared to sequential streams, especially when dealing with massive datasets.
101
111
-**Optimal Resource Utilization:** Multicore processors are fully utilized, making parallel streams ideal for performance optimization.
102
112
103
113
**Code Snippet and Benchmark Output:**
114
+
104
115
```java
105
116
// Populate the list with values
106
117
for (int i =0; i < datasetSize; i++) {
@@ -125,24 +136,27 @@ values.stream()
125
136
long sequentialEndTime =System.currentTimeMillis();
126
137
long sequentialTimeTaken = sequentialEndTime - sequentialStartTime;
127
138
```
139
+
128
140
**Scenario 1: Small Dataset (datasetSize = 10) Analysis:**
141
+
129
142
- The dataset is deliberately kept small to showcase the impact on performance.
130
143
- Parallel processing does not demonstrate a significant advantage due to the overhead of managing parallel threads which overshadows the potential advantages.
131
144
132
145
**Benchmark Output:**
146
+
133
147
```
134
148
Parallel Time Taken: 9 milliseconds
135
149
Sequential Time Taken: 0 milliseconds
136
150
```
137
151
138
-
**Scenario 2: Large Dataset
152
+
**Scenario 2: Large Dataset (datasetSize = 1,000,000) Analysis:**
139
153
140
-
(datasetSize = 1,000,000) Analysis:**
141
154
- Parallel streams potentially perform better when dealing with large datasets.
142
155
- The process of dividing the work among multiple threads becomes more advantageous for significant workloads.
143
156
- Multicore processors are utilized optimally, leading to shorter execution times compared to sequential streams.
144
157
145
158
**Benchmark Output:**
159
+
146
160
```
147
161
Parallel Time Taken: 2318 milliseconds
148
162
Sequential Time Taken: 7789 milliseconds
@@ -159,6 +173,7 @@ In Java, the use of parallel streams can significantly improve performance for c
159
173
- When multiple threads execute `println()` statements, the output becomes sequential.
160
174
161
175
**Example:**
176
+
162
177
```java
163
178
List<Integer> list =Arrays.asList(1, 2, 3, 4, 5);
164
179
@@ -176,6 +191,7 @@ list.forEach(value -> {
176
191
- The synchronous nature of the resource limits the full potential of parallelization.
177
192
178
193
**Example:**
194
+
179
195
```java
180
196
// Limited impact with parallel streams
181
197
System.out.println("\nParallel Stream:");
@@ -196,10 +212,12 @@ list.parallelStream()
196
212
Lazy evaluation means that operations on a stream are not executed until a terminal operation is invoked. This allows for efficient resource usage by processing only the elements necessary for the final result.
197
213
198
214
**How it Benefits:**
215
+
199
216
-**Efficient Resource Utilization:** Elements are processed on-demand, saving processing time and memory.
200
217
-**Suitable for Large Datasets:** Laziness ensures that the stream doesn't process the entire dataset if it's not required for the final result.
0 commit comments