In this post, we will cover following topics.
- What are Streams?
- What is a pipeline?
- Key points to remember for Streams.
- How to create Streams?
What are Streams?
Java 8 introduced new package java.util.stream
which contains classes to perform SQL-like operations on elements. Stream is a sequence of elements on which you can perform aggregate operations (reduction, filtering, mapping, average, min, max etc.). It is not a data structure that stores elements like collection but carries values often lazily computed from source through pipeline.
What is a pipeline?
A pipeline is sequence of aggregate (reduction and terminal) operations on the source. It has following components.
- A source: Collections, Generator Function, array, I/O channel etc.
- zero or more intermediate operations: filter, map, sequential, sorted, distinct, limit, flatMap, parallel etc. Intermediate operations returns/produces stream.
- a termination operation: forEach, reduction, noneMatch, allMatch, count, findFirst, findAny, min, max etc.
Key points to remember for Streams
- No storage.
- Functional in nature.
- Laziness-seeking.
- Possibly unbounded. Operations, for example, limit(n) or findFirst() can permit calculations on infinite streams to finish in finite time.
- Consumable. The elements can be visited only once. To revisit, you need to create a new stream.
How to create Streams?
1. In Collection
, you can create streams by calling stream()
, parallelStream()
.
Collection<Person> persons = StreamSamples.getPersons(); persons.stream().forEach(System.out::println); // parallel stream persons.parallelStream().forEach(System.out::println);
2. From Stream
interface, calling static factory method of()
which takes varargs of T
type.
Stream.of("This", "is", "how", "you", "create", "stream", "from", "static", "factory", "method").map(s -> s.concat(" ")).forEach(System.out::print);
3. From Arrays
class, by calling stream()
static method.
Arrays.stream(new String[] { "This", "is", "how", "you", "create", "stream", ".", "Above", "function", "use", "this" }).map(s -> s.concat(" ")) .forEach(System.out::print);
4. From Stream
by calling iterate()
. It is infinite stream function.
// iterate return infinite stream... beware of infinite streams Stream.iterate(1, i -> i++).limit(10).forEach(System.out::print);
5. From IntStream
by calling range
.
int sumOfFirst10PositiveNumbers = IntStream.range(1, 10).reduce(0, Integer::sum); System.out.println(sumOfFirst10PositiveNumbers);
6. From Random
by calling ints()
. It is infinite stream function.
// random.ints for random number new Random().ints().limit(20).forEach(System.out::println);
7. From BufferedReader
by calling lines()
. Streams of file paths can be obtained by calling createDirectoryStream
of Files
class and some other classes like JarFile.stream()
, BitSet.stream()
etc.
try (BufferedReader br = new BufferedReader(new StringReader(myValue))) { br.lines().forEach(System.out::print); System.out.println(); } catch (IOException io) { System.err.println("Got this:>>>> " + io); }
I hope the post is informative and helpful in understanding Streams. You can find the full example code on Github.
You can also read on Aggregate opeations on Stream.