85
Katsconf – September 2016 [email protected] Put the Lime in the Coconut 10 Best Practices for Java 8 10 Sets of Best Practices for Java 8

10 Sets of Best Practices for Java 8

Embed Size (px)

Citation preview

Page 1: 10 Sets of Best Practices for Java 8

Katsconf – September 2016

[email protected]

Put the Lime in the Coconut• 10 Best Practices for Java 8• 10 Sets of Best Practices for Java 8

Page 2: 10 Sets of Best Practices for Java 8

About this talk…

Page 3: 10 Sets of Best Practices for Java 8

I’ll Be Your Corporate Shill Today…

Page 4: 10 Sets of Best Practices for Java 8

How Many Of You Are Using Java 8?

Page 5: 10 Sets of Best Practices for Java 8

On With The Show!!!

Page 6: 10 Sets of Best Practices for Java 8

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

Page 7: 10 Sets of Best Practices for Java 8

Levels of Discussion

• High level principles

• Designing API’s

• Design in general

• Low level coding

• Pet peeves

Page 8: 10 Sets of Best Practices for Java 8

Its Been Amongst Us For Some Time…

Page 9: 10 Sets of Best Practices for Java 8

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

Page 10: 10 Sets of Best Practices for Java 8

* Or Clojure, Kotlin, Ceylon etc…

Page 11: 10 Sets of Best Practices for Java 8

Lambdas and Method References

Page 12: 10 Sets of Best Practices for Java 8

Replacing Anonymous Inner Classes

Page 13: 10 Sets of Best Practices for Java 8

Expression Vs. Block Lambdas

Page 14: 10 Sets of Best Practices for Java 8

Expression Vs. Block Lambdas

Page 15: 10 Sets of Best Practices for Java 8

Expression Lambdas Good, Block Lambdas Evil…

Page 16: 10 Sets of Best Practices for Java 8

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’

Page 17: 10 Sets of Best Practices for Java 8

Functional Interfaces

Page 18: 10 Sets of Best Practices for Java 8

Know Your Functional Interfaces

Page 19: 10 Sets of Best Practices for Java 8

Overloading and Functional Interfaces

Page 20: 10 Sets of Best Practices for Java 8

JavaDoc Guidelines for Functional Interfaces

Page 21: 10 Sets of Best Practices for Java 8

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

Page 22: 10 Sets of Best Practices for Java 8

Optional

Page 23: 10 Sets of Best Practices for Java 8

The Basics of Optional

Page 24: 10 Sets of Best Practices for Java 8

The Basics of Optional

Page 25: 10 Sets of Best Practices for Java 8

• 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

Page 26: 10 Sets of Best Practices for Java 8

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

Page 27: 10 Sets of Best Practices for Java 8

Feel the Evil…

Page 28: 10 Sets of Best Practices for Java 8

Streams and Collections

Page 29: 10 Sets of Best Practices for Java 8

Basic Use Of Streams

Page 30: 10 Sets of Best Practices for Java 8

Basic Use Of Streams

Page 31: 10 Sets of Best Practices for Java 8

Basic Use Of Streams

Page 32: 10 Sets of Best Practices for Java 8

Basic Use Of Streams

Page 33: 10 Sets of Best Practices for Java 8

Two Ways to Find the Average

NB I do know about ‘IntStream.average’ and ‘Collectors.averagingInt’ etc…

Page 34: 10 Sets of Best Practices for Java 8

Don’t Go Fully Functional in Java

Page 35: 10 Sets of Best Practices for Java 8

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

Page 36: 10 Sets of Best Practices for Java 8

Why Are Streams Read-Once?

Page 37: 10 Sets of Best Practices for Java 8

• 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

Page 38: 10 Sets of Best Practices for Java 8

The ‘Spliterator’ Interface

Page 39: 10 Sets of Best Practices for Java 8

The ‘Spliterator’ Interface

Page 40: 10 Sets of Best Practices for Java 8

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

Page 41: 10 Sets of Best Practices for Java 8

Using Collectors

Page 42: 10 Sets of Best Practices for Java 8
Page 43: 10 Sets of Best Practices for Java 8

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

Page 44: 10 Sets of Best Practices for Java 8

Streams and Boxing

Page 45: 10 Sets of Best Practices for Java 8

Streams and Boxing

Page 46: 10 Sets of Best Practices for Java 8

Streams and Boxing

Without: 1066 With: 2041 Difference: 975Without: 833 With: 1328 Difference: 495Without: 833 With: 1330 Difference: 497Without: 851 With: 1291 Difference: 440Without: 830 With: 1322 Difference: 492Without: 862 With: 1365 Difference: 503Without: 874 With: 1249 Difference: 375Without: 840 With: 1259 Difference: 419…Without: 851 With: 1239 Difference: 388Without: 830 With: 1253 Difference: 423Without: 843 With: 1231 Difference: 388Without: 825 With: 1232 Difference: 407Without: 835 With: 1260 Difference: 425Without: 837 With: 1244 Difference: 407Without: 841 With: 1244 Difference: 403Average difference is: 419.96

Page 47: 10 Sets of Best Practices for Java 8

Then I Showed This To David…

Page 48: 10 Sets of Best Practices for Java 8

Streams and Boxing

Page 49: 10 Sets of Best Practices for Java 8

Streams and Boxing

Page 50: 10 Sets of Best Practices for Java 8

Streams and Boxing

Page 51: 10 Sets of Best Practices for Java 8

Streams and Boxing

NB: Units are operations per second so bigger is better

Page 52: 10 Sets of Best Practices for Java 8

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

Page 53: 10 Sets of Best Practices for Java 8

Functional Programming With Strings

Page 54: 10 Sets of Best Practices for Java 8

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

Page 55: 10 Sets of Best Practices for Java 8

Manipulating Strings Using the Streams API

Page 56: 10 Sets of Best Practices for Java 8
Page 57: 10 Sets of Best Practices for Java 8

‘String.chars’ returns an ‘IntStream’

Page 58: 10 Sets of Best Practices for Java 8

Best Practises for Strings

• Avoid combining the Streams API with String objects

Page 59: 10 Sets of Best Practices for Java 8

Streams Outside Collections

Page 60: 10 Sets of Best Practices for Java 8

Using Streams with Zip Files

Page 61: 10 Sets of Best Practices for Java 8

Using Streams with Zip Files

Page 62: 10 Sets of Best Practices for Java 8

Using Streams with ‘BufferedReader’

Page 63: 10 Sets of Best Practices for Java 8

Using Streams with ‘BufferedReader’

Page 64: 10 Sets of Best Practices for Java 8

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

Page 65: 10 Sets of Best Practices for Java 8

Parallel Streams

Page 66: 10 Sets of Best Practices for Java 8

Be Warned!

Some people, when confronted with a problem, think "I know, I’ll use multi-threading". Nothhw tpe yawrve o oblems.

Page 67: 10 Sets of Best Practices for Java 8

Basic Parallel Streams

Page 68: 10 Sets of Best Practices for Java 8

Returning to our Benchmark

Page 69: 10 Sets of Best Practices for Java 8

Returning to our Benchmark

NB: Units are operations per second so bigger is better

Page 70: 10 Sets of Best Practices for Java 8

Its Not That Easy

Page 71: 10 Sets of Best Practices for Java 8

A More Complex Problem

Page 72: 10 Sets of Best Practices for Java 8

A More Complex Problem

NB: Units are operations per second so bigger is better

Page 73: 10 Sets of Best Practices for Java 8

Its Still Not That Easy

Page 74: 10 Sets of Best Practices for Java 8

Converting the Code to REST

Page 75: 10 Sets of Best Practices for Java 8

Sequential(GET /lines)

Parallel(GET /linesParallel)

1 Thread 100 Requests 24 9

100 Threads 20 Requests 825 775

200 Threads 20 Requests 2086 2103

300 Threads 20 Requests 3598 3487

Average Times Via JMeter (Smaller is Better)

Page 76: 10 Sets of Best Practices for Java 8

Its Still Still Not That Easy

Page 77: 10 Sets of Best Practices for Java 8

Doug Lea et al…http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html

Page 78: 10 Sets of Best Practices for Java 8

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

Page 79: 10 Sets of Best Practices for Java 8

Testing Your Parallel Collections

Page 80: 10 Sets of Best Practices for Java 8

OO Design Patterns and FP

Page 81: 10 Sets of Best Practices for Java 8

• 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

Page 82: 10 Sets of Best Practices for Java 8

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

Page 83: 10 Sets of Best Practices for Java 8

The Other Stuff

Page 84: 10 Sets of Best Practices for Java 8

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

Page 85: 10 Sets of Best Practices for Java 8

Thanks for Watching