Stream-related interfaces and classes are in the java.util.stream package.
AutoCloseable interface is from the java.lang package.
All stream interfaces inherit from the BaseStream interface, which inherits from the AutoCloseable interface.
AutoCloseable | +--BaseStream | +--IntStream | +--LongStream | +--DoubleStream | +--Stream<T>
If the streams use collections as their data source, and collections do not need to be closed.
If a stream is based on a closeable data source such as a file I/O channel, we can create the stream using a try-with-resources statement to get it closed automatically.
BaseStream interface defines all methods common to all types of streams.
Stream<T>
interface represents a stream of the element type T.
A Stream<Student> represents a stream of Studentobjects.
The Stream<T> interface contains methods such as filter(), map(), reduce(), collect(), max(), min(), etc.
When working with primitive types we can use
three specialized stream interfaces called IntStream
,
LongStream
, and DoubleStream
.
These interfaces provide methods to deal with primitive values.
For other primitive types such as float, short, byte, we can still use the three specialized stream interfaces.
In the following code we are going to use stream to calculate a sum of the squares of all odd integers in the list.
We will use the following steps to do the calculation.
The stream() method in the Collection interface returns a sequential stream. In this way the Collection acts as the data source.
The following code creates a List<Integer> and obtains a Stream<Integer> from the list:
List<Integer> numbersList = Arrays.asList(1, 2, 3, 4, 5); Stream<Integer> numbersStream = numbersList.stream();
Stream<T> filter()
uses a Predicate<T>
to keep elements if the specified Predicate returns true for that element.
The following statement obtains a stream of only odd integers:
Stream<Integer> oddNumbersStream= numbersStream.filter(n ->n % 2 == 1);
Stream<T> map()
uses a Function to map each element
in the stream and create a new stream.
The following statement maps a stream to their squares:
Stream<Integer> aStream = stream.map(n -> n * n);
reduce(T identity, BinaryOperator<T> accumulator)
reduces the stream to a single value.
It takes an initial value and an accumulator
that is a BinaryOperator<T>
as
arguments.
reduce(T identity, BinaryOperator<T> accumulator)
performs a reduction on the elements of this stream, using the
provided initial value and an associative accumulation function,
and returns the reduced value.
This is equivalent to:
T result = identity; for (T element : this stream) result = accumulator.apply(result, element) return result;
The following code sums all integers in the stream.
int sum = aStream.reduce(0, (n1, n2) -> n1 + n2);
The Integer.sum()
method performs sum of two integers.
We can rewrite the code using a method reference.
int sum = aStream.reduce(0, Integer::sum);
The following code links each step together.
import java.util.Arrays; import java.util.List; //from w w w .ja va 2 s .c om public class Main { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int sum = numbers.stream() .filter(n -> n % 2 == 1) .map(n -> n * n) .reduce(0, Integer::sum); System.out.println(sum); } }
The code above generates the following result.
A stream can be ordered or unordered.
An ordered stream keeps the order of its elements.
The Streams API can convert an ordered stream, which may represent an ordered data source such as a list or a sorted set, into an unordered stream.
We can also convert an unordered stream into an ordered stream by applying an sorting intermediate operation.
import java.util.Arrays; import java.util.List; /* ww w . j ava 2s . c o m*/ public class Main { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(3,7,9,3,1,2,1, 2, 3, 4, 5); numbers.stream() .filter(n -> n % 2 == 1) .sorted() .forEach(System.out::println); } }
The code above generates the following result.