IntStream
, LongStream
, DoubleStream
Java provides specialized stream interfacesβIntStream
, LongStream
, and DoubleStream
βto efficiently handle primitive data types without the overhead of boxing and unboxing that occurs when using generic Stream<T>
with wrapper classes like Integer
or Double
.
sum()
, average()
, range()
, which are optimized for primitives.StreamT
Feature | Stream<T> |
Primitive Streams (IntStream , etc.) |
---|---|---|
Element Type | Object (e.g., Integer ) |
Primitive (int , long , double ) |
Boxing/Unboxing Overhead | Yes | No |
Specialized Methods | General methods | Numeric-specific (e.g., sum() , average() ) |
Conversion Methods | mapToInt() , mapToLong() , etc. |
Can convert to/from Stream<T> |
IntStream
example: sum and average
import java.util.stream.IntStream;
public class IntStreamExample {
public static void main(String[] args) {
IntStream numbers = IntStream.of(1, 2, 3, 4, 5);
int sum = numbers.sum();
System.out.println("Sum: " + sum); // Output: Sum: 15
// To reuse the stream, recreate it:
double average = IntStream.of(1, 2, 3, 4, 5).average().orElse(0);
System.out.println("Average: " + average); // Output: Average: 3.0
}
}
LongStream
example: generating ranges
import java.util.stream.LongStream;
public class LongStreamExample {
public static void main(String[] args) {
long sum = LongStream.rangeClosed(1, 5).sum();
System.out.println("Sum of 1 to 5: " + sum); // Output: 15
}
}
DoubleStream
example: statistics
import java.util.stream.DoubleStream;
public class DoubleStreamExample {
public static void main(String[] args) {
DoubleStream doubles = DoubleStream.of(1.5, 2.5, 3.5);
double max = doubles.max().orElse(Double.NaN);
System.out.println("Max: " + max); // Output: Max: 3.5
}
}
Primitive streams avoid the overhead of boxing/unboxing that occurs in generic streams, which can significantly improve performance in numerical computations, especially on large datasets or in tight loops.
Using these specialized streams is a best practice when dealing with primitive data, combining clean code with efficient execution.
Java Streams provide convenient methods to convert between object streams (e.g., Stream<Integer>
) and primitive streams (IntStream
, LongStream
, DoubleStream
). This conversion is essential to combine the expressive power of object streams with the performance benefits of primitive streams.
mapToInt(ToIntFunction<? super T> mapper)
mapToLong(ToLongFunction<? super T> mapper)
mapToDouble(ToDoubleFunction<? super T> mapper)
These methods apply a mapping function that extracts the primitive value from each object and returns the corresponding primitive stream.
boxed()
converts a primitive stream back into a Stream
of wrapper objects, e.g., from IntStream
to Stream<Integer>
.IntStream
and Backimport java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class ConversionExample1 {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4);
// Convert Stream<Integer> to IntStream
IntStream intStream = numbers.stream()
.mapToInt(Integer::intValue);
// Sum of primitive ints
int sum = intStream.sum();
System.out.println("Sum: " + sum); // Output: Sum: 10
// Convert IntStream back to Stream<Integer>
Stream<Integer> boxedStream = IntStream.range(1, 5).boxed();
boxedStream.forEach(System.out::println);
}
}
DoubleStream
import java.util.List;
public class ConversionExample2 {
public static void main(String[] args) {
List<String> prices = List.of("9.99", "19.95", "5.50");
// Convert Stream<String> to DoubleStream
double total = prices.stream()
.mapToDouble(Double::parseDouble)
.sum();
System.out.println("Total price: " + total); // Output: Total price: 35.44
}
}
import java.util.List;
import java.util.Objects;
public class ConversionExample3 {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, null, 3, 4);
// Map to IntStream carefully, filtering out nulls first
int sum = numbers.stream()
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.sum();
System.out.println("Sum ignoring nulls: " + sum); // Output: 8
}
}
mapToInt()
, mapToLong()
, and mapToDouble()
to convert object streams to primitive streams.boxed()
to convert primitive streams back to object streams.NullPointerException
.Primitive streams such as IntStream
, LongStream
, and DoubleStream
provide specialized operations tailored to numeric data processing. These operations simplify common statistical calculations, making the code more concise and efficient by avoiding boxing overhead.
sum()
: Computes the total of all elements.average()
: Calculates the mean as an OptionalDouble
.min()
/ max()
: Finds the smallest or largest element, returned as OptionalInt
, OptionalLong
, or OptionalDouble
.range(startInclusive, endExclusive)
: Generates a stream of numbers from a start (inclusive) to an end (exclusive).import java.util.stream.IntStream;
public class PrimitiveOperations1 {
public static void main(String[] args) {
IntStream numbers = IntStream.of(10, 20, 30, 40, 50);
int sum = numbers.sum();
System.out.println("Sum: " + sum); // Output: Sum: 150
// Need to recreate stream for average, as streams are single-use
double average = IntStream.of(10, 20, 30, 40, 50).average().orElse(0);
System.out.println("Average: " + average); // Output: Average: 30.0
}
}
import java.util.stream.LongStream;
public class PrimitiveOperations2 {
public static void main(String[] args) {
LongStream values = LongStream.of(100L, 200L, 50L, 400L, 300L);
long min = values.min().orElseThrow();
System.out.println("Min value: " + min); // Output: Min value: 50
// Recreate stream for max
long max = LongStream.of(100L, 200L, 50L, 400L, 300L).max().orElseThrow();
System.out.println("Max value: " + max); // Output: Max value: 400
}
}
range()
to Generate and Sum a Range of Numbersimport java.util.stream.IntStream;
public class PrimitiveOperations3 {
public static void main(String[] args) {
int sumRange = IntStream.range(1, 6) // 1 to 5 inclusive of 1, exclusive of 6
.sum();
System.out.println("Sum of range 1 to 5: " + sumRange); // Output: 15
}
}
Primitive stream operations provide a clean and efficient way to perform numeric calculations without manual looping or boxing. Methods like sum()
, average()
, min()
, and max()
are concise and return meaningful results wrapped in optionals when necessary, reducing boilerplate and improving readability. Additionally, range()
and rangeClosed()
help quickly generate numeric sequences for processing, enhancing productivity when working with numeric datasets.