6. 1. General points about adopting Java 8
2. Using Lambdas and Method Refs
3. Coping with Functional Interfaces
4. Adding ‘Optional<T>’ into your codebase
5. The Streams API and Collections
6. Using Streams outside of collections
7. Functional programming with strings
8. Adding parallelism to streams
9. Simplifying Design Patterns with FP
10. The remainder of Java 8
Sets of Best Practises
7. Levels of Discussion
• High level principles
• Designing API’s
• Design in general
• Low level coding
• Pet peeves
9. Best Practises for Management
• You can’t avoid Java 8
• So plan for the pain of change…
• The future is (kinda) functional
• Your developers may already be
eager to embrace it
• Explore other JVM languages
• Exploring != adopting
• Don’t accidentally encourage
use of anti-patterns in Java 8
16. Best Practises for Lambdas and Method Refs
• obj::foo not x -> obj.foo(x)
• Only write lambdas which
have ‘obviously no errors’
• When in doubt prefer method
references to lambdas
• Don’t use block lambdas
• Eliminate superfluous syntax
• Including final on variables
which are ‘effectively final’
21. Best Practises for Functional Interfaces
• Learn the functional interfaces
• Consider rewriting abstract
classes as functional
interfaces
• Avoid overloading with related
functional interfaces
• Only write your own functional
interfaces when unavoidable
• Follow the naming guidelines
when you write your own
• Use @FunctionalInterface
25. • optional.ifPresentOrElse(this::foo, this::bar)
• Optional<Account> opt = homeAcct(id).or(() -> workAcct(id))
• List<Email> emails = staff.stream()
.map(e -> e.getAddress())
.flatMap(Optional::stream)
.collect(toList())
New Optional Features in Java 9
//may not exist
26. Best Practises for Option
• Never return null from a
method in your public API
• Return an Option instead
• Consider whether to require
Option within your codebase
• Consider if Option as a
parameter is useful to you
• Never return null from a
method that declares Option
Be conservative in what you send, be
liberal in what you accept
Robustness Principle / Postel's Law
35. Best Practises for Streams and Collections Pt1
• Be judicious in your use of the
‘functional toolkit’
• The methods of the toolkit
are patterns of iteration
• Not every use of iteration
cleanly fits the pattern
• Don’t obsess about local state
• Its global state that’s bad
37. • Streams are typically explained like UNIX pipes
• Each call creates a temporary result which is passed on
• The reality is somewhat different
• A stream pipeline is made up of a source, zero or more
intermediate operations and a terminal operation
• The terminal operations typically:
• Produce an aggregate value (e.g. reduce and collect)
• Select a particular item (e.g. findAny and findFirst)
• Iterate over the items (forEach)
• The operations you specify produce a stream description
• This description is executed at the terminal operation
• Each stage of the pipeline has a set of flags
• These can be used to take shortcuts
Understand How Streams Work Internally
40. Best Practises for Streams and Collections Pt2
• Its good to return streams
from the methods of your API
• Items can be fetched lazily
• The ‘toolkit’ is right there
• Regular collections are
easy to build from streams
• But not in every case
• Typically when the data
source might change
43. Best Practises for Streams and Collections Pt3
• Understand how streams
(may) work ‘under the hood’
• Fetching may be lazy
• Actions will be postponed
till the termination
• Shorts-cuts can be taken
• Write code in ‘sympathy’
• In particular become
familiar with Collectors
52. Best Practises for Streams and Collections Pt4
• Be aware of the overhead of
boxing when using types such
as ‘Stream<Double>’
• Use the specialized types
like ‘DoubleStream’ instead
54. Examples of FP With Strings in Other Languages
class Program {
static void Main(string[] args) {
string input = " abc-def#ghi+jkl ";
string output = RemovePunctuation(input);
Console.WriteLine(output);
}
private static string RemovePunctuation(string input) {
var letters = from c in input.ToLower()
where c >= 'a' && c <= 'z'
select c;
return new string(letters.ToArray());
}
}
abcdefghijkl
64. Best Practises for Streams and Types
• Remember streams are for
more than collections
• Keep an eye as JSE libraries
and open source projects
incrementally add support
• Reactive Streams are coming
in Java 9
77. Doug Lea et al…
http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html
78. Best Practises for Parallel Streams
• Parallel isn’t a panacea
• Parallel isn’t a panacea
• Parallel isn’t a panacea
• ParParallelallel isn’tn’tn’t
aaaaaaaaaaaa panacea
• Use it when the data and
task have the right ‘shape’
• Test correctly to confirm
there is real world benefit
81. • Patterns are fixes for issues in some style of programming
• Places where the toolkit provided by your language is weak
• Both OO and FP languages have associated patterns
• The OO and FP styles of programming compliment one another
• The use of one can remove the need for a pattern in the other
• We have already seen an example
• The ‘Optional’ type replaces the ‘Null Object’ Pattern
• Having lambdas reduces the need for ‘objects as tasks’
• For example in the Command Pattern we can have a table of
lambdas instead of a table of instances of anonymous types
OO Design Patterns and FP
82. Best Practises for Design Patterns
• Look again at your design
and its use of patterns
• Could these be reduced
or removed via FP?
• Pay particular attention
were objects model tasks
• Command
• Observer
• Strategy
• Visitor
84. Best Practises for Other Features
• Annotations can be repeated!
• Refactor away ugliness
• Use the new Date/Time API
• JodaTime is now legacy
• Be aware that annotations
can appear just about
anywhere
• Benchmarking?
• Code generation?
• Prepare for modules in Java 9