Flashcards in Stream API Deck (13)
Intermediate stream operation which is executed once a terminal operation is reached.
Intermediate operations return a new stream. They are always lazy; executing an intermediate operation such as filter() does not actually perform any filtering, but instead creates a new stream that, when traversed, contains the elements of the initial stream that match the given predicate. Traversal of the pipeline source does not begin until the terminal operation of the pipeline is executed.
Stateless vs. Stateful Intermediate Operations
- Stateless : each object is processed independently (i.e: filtering)
- Stateful : processing of each element may depend on the other objects in the same stream (i.e: sorting)
Streams that handle primitives
- Stream -> Object of type T
- DoubleStream -> double
- IntStream -> int
- LongStream -> long
They all extend BaseStream
Basic Ways of getting a Stream instance
When using a collection object (i.e: ArrayList) :
- Call the stream() method
- Call the parallelStream() method
When using Arrays class :
- Call the static method stream(T array)
1) Reduction operations
2) forEach() / forEachOrdered()
Forms of Stream.reduce() method.
Explain their uses
1) Optional< T > reduce(BinaryOperator< T > accumulator)
2) T reduce(T identityVal, BinaryOperator < T > accumulator)
3) < U > U reduce(U identity, BiFunction< U > accumulator, BinaryOperator< U > combiner)
1) Basic, non-parallel Stream reduction
2) DON'T KNOW : What is the purpose of the identityVal parameter?
3) Used when parallel Streams are used. Each sub-stream is reduced using the accumulator function, whereas the combiner combines the final results of each sub-stream into the "grand total" result
TODO: Why does the second form not use Optional?
BinaryOperator< T > is a functional interface used in reduction operations.
1) Name the default method signature
2) Its purpose in reduction operations
3) Describe the purpose of each of the arguments in this method when used in Stream reduction operations
1) T apply(T val1, T val2)
2) Takes in 2 values and returns a new value based on those values thus "reducing" the number of elements
3) As follows:
a) First operand (val1) holds the collective value aggregated or derived from the elements encountered so far which will be of the same type as the type of elements in the stream.
b) Second operand (val2) holds the value which is encountered next as the unprocessed value in the stream.
For example (a,b) -> a + b
a = the sum of all elements thus far
b = the next value to be added
What kind of Collection will yield an ordered Stream when calling the stream() or parallelStream() method?
An ordered Collection (i.e: TreeSet)
TODO: verify this since it is an assumption. Text was not clear enough
What Stream method yields an unordered version of the Stream?
To iterate through a Stream in
a) Ordered fashion, you call method X
b) Unordered fashion, you call method Y
TODO: need to understand the benefits of each in relationship to parallel/sequential Streams
Write the signatures of the 4 versions of Stream.map()
1) < R > Stream< R > map(Function < ? super T, ? extends R > mapFunc)
2) IntStream mapToInt(ToIntFunction < ? super T > mapFunc)
3) LongStream mapToLong(ToLongFunction < ? super T > mapFunc)
4) DoubleStream mapToDouble(ToDoubleFunction < ? super T > mapFunc)
Function has abstract method signature
R apply(T val)
It's purpose is to transform __ to __
a) T to R
b) R to T