Java Streams
Java Streams
- A stream in Java is a sequence of data that takes input from Collections or IO Channels
- Streams don’t change the original data structure.
- A Stream Pileline is the operation (STREAM OPERATIONS) that run on a stream to produce a result
- Each intermediate operation is lazily executed and returns a stream as a result.
- Terminal operations mark the end of the stream and return the result.
- Finite Streams have a limit
- infinite Streams are like sunrise/sunset cycle
re-stream a List each time. Dont Re-use a stream because “creating” a Stream just points at the existing data structure behind the scenes; it does not copy the data.
Streams
- Do not support indexed access
- finFirst() can give top of the element, but not the second or third or last element
- Simple syntax to build a List or array from a Stream
Three common ways to make a Stream
- list.stream() – From ArrayList
- Stream.of(arrayOfObjects) [not array of primitives!]
Student[] students = {....}; Stream<Student> studentStream = Stream.of(students).map(…).filter(…).other(…);//No Terminal Operator
- Stream.of(val1, val2, …) – Individual elements
Student s1 = …; Student s2 = …; Stream<Student> studentStream = Stream.of(s1,s2, ...).map(…).filter(…).other(…);;//No Terminal Operator
Outputting Streams
Getting a List out of a Stream
List<SomeClass> list = someStream.map(…).collect(Collectors.toList());
Getting an Array out of a Stream
//Fill elements into an Array from a Stream
Student[] studentArray = someStream.map(someLambda).toArray(Student[]::new);
String[] strArray = stringStream.filter(...).map(...).toArray(String[]::new);
Student[] studentArray = studentStream.toArray()
What Cannot be done with Streams forEach
- Multiple Loops are not possible as for each is a Terminal operation consuming a Stream.
- Local variable modification
list.stream().forEach(e -> total += e);
- do this with “map” and “reduce”.
- Or use builtin “sum” method of DoubleStream or Int Stream
- Cannot use break or return within forEach loop
It uses a stateful lambda expression.
Stream Operations
- SOURCE : Where the stream comes from
-
INTERMEDIATE OPERATIONS : Transforms the stream into another stream.
STREAMS USE LAZY EVALUATION.
- map: The map method is used to returns a stream consisting of the results of applying the given function to the elements of this stream.
- filter: The filter method is used to select elements as per the Predicate passed as argument.
- sorted: The sorted method is used to sort the stream.
- The intermediate operations do not run until the terminal operation runs.
-
TERMINAL OPERATION: Actually produces a result. Stream becomes invalid
after terminal operation
- collect: The collect method is used to return the result of the intermediate operations performed on the stream.
- forEach: The forEach method is used to iterate through every element of the stream.
- reduce: The reduce method is used to reduce the elements of a stream to a single value. The reduce method takes a BinaryOperator as a parameter.
Non-Terminal Operations
filter() map() flatMap() distinct() limit() peek()
Terminal Operations
anyMatch() allMatch() noneMatch() collect() count() findAny() findFirst() - returns Optional forEach() min() max() reduce() toArray()