Java Stream boxed Method
last modified June 1, 2025
The boxed
method in Java Streams is a crucial operation when
working with primitive streams. This tutorial explains its purpose, use cases,
and provides practical examples.
Stream.boxed is an intermediate operation that converts a primitive
stream (IntStream
, LongStream
, or DoubleStream
)
into a Stream
of corresponding
wrapper objects (Stream<Integer>
, Stream<Long>
, or
Stream<Double>
). This operation is known as "boxing" -
converting primitive values to their object equivalents.
The boxed operation is particularly useful when you need to work with APIs that require object streams rather than primitive streams, or when you need to use operations that aren't available on primitive streams.
Primitive vs Object Streams
Java distinguishes between primitive streams (IntStream
,
LongStream
, DoubleStream
) and object streams
(Stream<T>
). Primitive streams are optimized for performance
and memory usage, but sometimes you need to convert them to object streams to
use certain APIs or operations. The boxed
method bridges this gap
by converting primitive values to their corresponding wrapper objects.
Primitive Stream | Boxed Equivalent | Boxing Method | Unboxing Method |
---|---|---|---|
IntStream | Stream<Integer> | boxed() | mapToInt(Integer::intValue) |
LongStream | Stream<Long> | boxed() | mapToLong(Long::longValue) |
DoubleStream | Stream<Double> | boxed() | mapToDouble(Double::doubleValue) |
The boxed
method is used to convert primitive streams to their
object equivalents, allowing you to use standard Stream
operations
that aren't available on primitive streams. Conversely, unboxing methods like
mapToInt
, mapToLong
, and mapToDouble
convert object streams back to primitive streams for performance-sensitive
operations.
Basic boxed Usage
This example demonstrates the most basic use of the boxed
method to convert an
IntStream to a Stream<Integer>.
void main() { IntStream.range(1, 5) .boxed() // Convert IntStream to Stream<Integer> .forEach(System.out::println); }
Here we create an IntStream
with values 1 through 4, then convert
it to a Stream<Integer> using boxed
. This allows us to use
standard Stream
operations that aren't available on primitive
streams.
$ java Main.java 1 2 3 4
Collecting Primitive Streams
One common use case for boxed
is when you need to collect primitive
stream elements into collections that can't store primitive values.
void main() { List<Integer> numbers = IntStream.of(10, 20, 30) .boxed() .toList(); System.out.println(numbers); }
Since Collections can only hold objects, we need to box the primitive int values
before collecting them into a List
. The boxed
operation performs this conversion automatically.
$ java Main.java [10, 20, 30]
Using with Stream Operations
Some Stream operations are only available on object streams. This example shows
using boxed
to enable these operations.
void main() { DoubleStream.of(1.1, 2.2, 3.3) .boxed() // Convert to Stream<Double> .sorted((a, b) - b.compareTo(a)) // Reverse sort .forEach(System.out::println); }
The sorted
method with a custom comparator isn't available on
DoubleStream
, so we first convert to
Stream<Double>
using boxed
. This gives us access
to all Stream
operations.
$ java Main.java 3.3 2.2 1.1
Boxed for Grouping and Collecting
The boxed
method is useful when you want to group or collect
primitive values using collectors that require objects, such as grouping numbers
by even/odd.
void main() { Map<String, List<Integer>> grouped = IntStream.rangeClosed(1, 10) .boxed() .collect(Collectors.groupingBy(n -> n % 2 == 0 ? "Even" : "Odd")); System.out.println(grouped); }
This example groups numbers from 1 to 10 into even and odd categories using
Collectors.groupingBy
. Since collectors work with objects,
boxed
is necessary to convert the primitive stream.
Combining with Other Streams
When you need to combine primitive streams with object streams,
boxed
becomes essential.
void main() { Stream.concat( IntStream.range(1, 4).boxed(), Stream.of("a", "b", "c") ).forEach(System.out::println); }
The Stream.concat
method requires both parameters to be of the same
type (Stream<T>
). We use boxed
to convert the
IntStream
to Stream<Integer>
so it can be
concatenated with Stream<String>
.
$ java Main.java 1 2 3 a b c
Performance Considerations
While boxed
is convenient, it has performance implications due to
object creation. This example demonstrates the overhead.
void main() { long start, end; // Without boxing start = System.nanoTime(); int sum1 = IntStream.range(0, 1_000_000).sum(); end = System.nanoTime(); System.out.println(sum1); System.out.println("Primitive sum: " + (end - start) + " ns"); // With boxing start = System.nanoTime(); int sum2 = IntStream.range(0, 1_000_000) .boxed() .reduce(0, Integer::sum); end = System.nanoTime(); System.out.println(sum2); System.out.println("Boxed sum: " + (end - start) + " ns"); }
The boxed version requires creating 1,000,000 Integer
objects and
then converting them back to primitives for summing. The primitive version
operates directly on primitive values without this overhead.
$ java Main.java 1783293664 Primitive sum: 15442200 ns 1783293664 Boxed sum: 61258700 ns
Alternative to boxed
In some cases, mapToObj
can be used as an alternative to
boxed
, especially when you need to perform additional
transformations.
void main() { IntStream.range(0, 5) .mapToObj(i - "Item " + i) // Alternative to boxed .forEach(System.out::println); }
Here we use mapToObj
to both convert the int values to objects and
transform them into strings. This is more efficient than using
followed by
map
when you need both operations.
$ java Main.java Item 0 Item 1 Item 2 Item 3 Item 4
Working with Optional
When dealing with Optional
results from primitive streams,
boxed
helps convert to Optional
of the wrapper type.
void main() { OptionalDouble avg = DoubleStream.of(1.5, 2.5, 3.5).average(); // Convert OptionalDouble to Optional<Double> Optional<Double> boxedAvg = avg.stream().boxed().findFirst(); boxedAvg.ifPresent(d - System.out.println("Average: " + d)); }
Primitive stream terminal operations return Optional
variants
(OptionalInt
, OptionalLong
,
OptionalDouble
). The boxed
method helps convert these to regular Optional<T>
when
needed.
$ java Main.java Average: 2.5
Source
Java IntStream.boxed Documentation
The boxed
method is an essential tool when working with Java
Streams, particularly when you need to bridge between primitive and object
streams. While it introduces some overhead, it enables powerful stream
operations that wouldn't otherwise be possible with primitive streams.
Author
List all Java tutorials.