Lambdas and Streams
In Java8, some of the things that are added:
- lambdas, functional interface, method references -> create function objects
- streams -> processing sequence of data elements
- Item 42: Prefer lambdas to anonymous class
- Item 43: Prefer method references to lambdas
- Item 44: Favour the use of standard functional interfaces
- Item 45: Use streams judiciously
- Item 46: Prefer side-effect-free functions in streams
- Item 47: Prefer Collection to Stream as a return type
- Item 48: Use caution when making streams parallel
Item 42: Prefer lambdas to anonymous class
abstract class with single
function objects: instances of function types
- Limited to functional interfaces (only one method required to be implemented by function objects)
- Lambda expressions can be used to make instances of functional interfaces.
- Java infers type, sometimes explicitly required
- Use generic instead of raw types for type inference, else explicit and verbose code would be needed
- Use them only if they make the code clearer and easy to understand
- Can not obtain a reference of itself.
thisrefers to enclosing instance
When to use Anonymous class
- If functional object is large, lambda becomes difficult to understand
thisto refer to newly created instance
- Functional type has multiple
Lambdas and Anonymous class are not reliable for serialization and deserialization. Avoid them, use
private static nested class instead if possible.
Item 43: Prefer method references to lambdas
method references: even more concise way to create function objects than lambda.
Where method references are shorter and clearer, use them; where they aren’t, stick with lambdas.
Item 44: Favour the use of standard functional interfaces
If one of the standard functional interfaces does the job, you should generally use it in preference to a purpose-built functional interface.
These are some of the 43 functional interfaces, the rest are derivations of these.
Use custom functional interface, if:
- It will be commonly used and could benefit from a descriptive name.
- It has a strong contract associated with it.
- It would benefit from custom
- Always annotate your functional interfaces with the
Don’t write overloadings that take different functional interfaces in the same argument position like the
submit() method of
Item 45: Use streams judiciously
- The streams API was added in Java 8 to ease the task of performing bulk operations, sequentially or in parallel. It consist of source stream, >=0 intermediate operation and one terminal operation.
- Stream pipelines are evaluated lazily: evaluation doesn’t start until the terminal operation is invoked, and data elements that aren’t required in order to complete the terminal operation are never computed.
- The streams API is fluent: it is designed to allow all of the calls that comprise a pipeline to be chained into a single expression
- Overusing streams makes programs hard to read and maintain.
- Using helper methods is even more important for readability in stream pipelines than in iterative code
- Refactor existing code to use streams and use them in new code only where it makes sense to do so, resist the urge.
Use code block
- want to read and modify local variables in scope
returnfrom enclosing method,
- uniform transformation of sequences
- filter sequences
- combine with a single operation or attribute
- search on basis of a criterion
Item 46: Prefer side-effect-free functions in streams
- Streams is based on a functional paradigm. To make the most out of it adopt both the paradigm and the API.
- Structure the code as a sequence of pure functions (use the output of the previous function as input and don’t use/modify local state).
forEachoperation should be used mostly to report the result of a stream computation, not to perform the computation.
- In order to use streams properly, we have to know about collectors. The most important collector factories are
Item 47: Prefer Collection to Stream as a return type
Initially collection interfaces like
Arrays were used.
The decision to choose was simple:
- If can’t implement
- If primitive elements are involved and performance is a concern -> Arrays
Stream added in Java8 complicated the matters a bit.
Iterable are not compatible with each other even though they have same iterator methods because
Stream doesn’t implement
Iterable. They can be interchanged by writing trivial adapters.
Collection or an appropriate subtype is generally the best return type for a
public, sequence returning method as it would implement both
Return a small enough sequence using
HashSet but don’t store a large sequence to later return like a
Collection as it has
Integer.MAX_VALUE limit. Use
Iterable for large sequences.
Item 48: Use caution when making streams parallel
Writing concurrent programs in Java keeps getting easier, but writing concurrent programs that are correct and fast is as difficult as it ever was.
Safety and liveness violations are a fact of life in concurrent programming, and parallel stream pipelines are no exception.
- Parallelizing a pipeline is unlikely to increase its performance if the source is from
Stream.iterate, or the intermediate operation
Performance gains from parallelism are best on streams over
ConcurrentHashMapinstances; arrays; int ranges; and long ranges because they can be accurately and cheaply split into subranges of any desired sizes and divide for parallel work. Stream use spliterator for this. The other reason is the good - to excellent locality of reference which is of much use in efficient parallel processing.
The terminal operation should be of reducing nature (like
count) for faster results.
collectmethod isn’t good as combining streams is costly. All others are intermediate candidates.
Streamspecification places stringent requirements on the function objects like
filterand programmer supplied. Adhere to them before parallelising else safety and correct result is compromised.
- Under the right circumstances, it is possible to achieve near-linear speedup in the number of processor cores simply by adding a parallel call to a stream pipeline. Always try thoroughly before choosing.
This is it!