Numerical streams in Java, part of the Stream API introduced in Java 8, are specialized streams for handling primitive numeric types (int, long, double) to avoid the overhead of boxing/unboxing in regular object streams. They include IntStream, LongStream, and DoubleStream, found in the java.util.stream package. These streams are optimized for numerical computations and provide specific operations for primitive types.
Important Features of Numerical Streams
- Avoid Boxing/Unboxing: Work directly with primitives (e.g., int instead of Integer), improving performance.
- Specialized Operations: Offer methods like sum(), average(), min(), max(), and range() tailored for numeric computations.
- Creation: Can be created from arrays, ranges, or other sources using methods like IntStream.of(), IntStream.range(), or mapping from object streams.
Creating Numerical Streams
- From Values:
IntStream intStream = IntStream.of(1, 2, 3, 4);
2. From Arrays:
int[] numbers = {1, 2, 3, 4};
IntStream intStream = Arrays.stream(numbers);
   3. From Ranges:
IntStream range = IntStream.range(1, 5); // [1, 2, 3, 4]
IntStream rangeClosed = IntStream.rangeClosed(1, 5); // [1, 2, 3, 4, 5]
Code language: JavaScript (javascript)
4.From Object Streams:
Stream<Integer> stream = Stream.of(1, 2, 3);
IntStream intStream = stream.mapToInt(Integer::intValue);
Code language: HTML, XML (xml)
Special Stream Operations
Numerical streams provide operations optimized for numeric data, including:
1 Aggregate Operations:
-
- sum(): Returns the sum of elements.
int sum = IntStream.of(1, 2, 3).sum(); // 6
Code language: JavaScript (javascript)
average(): Returns an OptionalDouble with the average.
OptionalDouble avg = IntStream.of(1, 2, 3).average(); // 2.0
Code language: JavaScript (javascript)
min(): Returns an OptionalInt with the minimum value
OptionalInt min = IntStream.of(1, 2, 3).min(); // 1
Code language: JavaScript (javascript)
max(): Returns an OptionalInt with the maximum value
OptionalInt max = IntStream.of(1, 2, 3).max(); // 3
Code language: JavaScript (javascript)
2. Range-Based Operations:
- range(start, end): Generates numbers from start (inclusive) to end (exclusive).
- rangeClosed(start, end): Includes both start and end
IntStream.range(1, 3).forEach(System.out::println); // Prints 1, 2
IntStream.rangeClosed(1, 3).forEach(System.out::println); // Prints 1, 2, 3
Code language: PHP (php)
3. Mapping to Other Streams:
- mapToObj: Converts to an object stream
Stream<String> strings = IntStream.of(1, 2, 3).mapToObj(i -> "Num: " + i);
Code language: JavaScript (javascript)
- mapToDouble or mapToLong: Converts to another numerical stream type
DoubleStream doubles = IntStream.of(1, 2, 3).mapToDouble(i -> i * 1.5);
4. Summary Statistics:
- summaryStatistics(): Returns an IntSummaryStatistics object with count, sum, min, max, and average.
IntSummaryStatistics stats = IntStream.of(1, 2, 3).summaryStatistics();
System.out.println(stats.getCount()); // 3
System.out.println(stats.getSum()); // 6
System.out.println(stats.getAverage()); // 2.0
Code language: JavaScript (javascript)
Performance Considerations
- Numerical streams are more efficient than object streams for primitive operations due to reduced boxing/unboxing.
- Use mapToInt, mapToDouble, or mapToLong when converting from object streams to avoid unnecessary boxing.
- Be cautious with large ranges or infinite streams (e.g., IntStream.iterate) to avoid memory issues; always use limit() when needed.
Limitations
- Numerical streams are specialized for primitives, so they lack some flexibility of object streams (e.g., no direct support for complex objects).
- Operations like collect are limited compared to Stream; use boxed() to convert to a regular stream if needed.
Numerical streams in Java 8 offer a powerful way to work with primitive data types efficiently. By avoiding the overhead of boxing and unboxing, they provide performance benefits and specialized operations tailored for numerical computations. Understanding and leveraging these streams can lead to more efficient and expressive code when dealing with primitive data.