SlideShare a Scribd company logo
1 of 92
Download to read offline
Jaffna Meetup 04
JAVA 8
Brought to you by WSO2
November 2016
1
Reference book
• Based on training done by Sameera Jayasoma (Associate Director/Architect @ wso2)
• I’ve used the book “Java 8 In Action” as the reference book.
• You can get all the sample sources from here.
2
What’s new in Java 8?
• Lambda Expressions
• Default Methods
• Method references
• Type Annotations and Pluggable Type Systems
• Repeating Annotations
• Method Parameter Reflection.
• Security Enhancements.
• Streams/Parallel Streams
• Optional
• Nashorn
• New Date and Time API
• No more permanent Generation
3
Why Java 8?
• More concise code
• Simpler use of multicore processors
• No official support for previous versions
4
Memory management
5
-XX:MetaspaceSize
Functions as Values in Java 8
• Java 8 now treats Functions, or in other words methods as
first-class citizens.
• Java used to treat primitives and object as first-class
citizens.
• This allows us to pass methods around at runtime. This
proved to be very useful in other functional languages.
6
Behaviour Parameterization
• Is a software development pattern
• easy to handle software requirement changes.
• Allows a block of code to be executed later
• You can pass this block of code as an argument to a method.
• Now this method’s behaviour depends on the behaviour of
this block of code.
• This is called behaviour parameterization.
• Consider a pet store. How do you filter out all the cats from
the pet store?
7
Attempt 1: Filtering Cats
• A first solution would look like following.
8
public static List<Pet> filterCats(List<Pet> petList) {
List<Pet> catList = new ArrayList<>();
for (Pet pet : petList) {
if ("cat".equals(pet.getCategory())) {
catList.add(pet);
}
}
return catList;
}
• But now you need to filter pets who are more than 12 months
older?
• What would you do?
• Introduce another duplicate method?
Attempt 2: Parameterizing the age
• You can parameterize the age and be more flexible to such
changes
9
public static List<Pet> filterPetsByAge(List<Pet> petList, int age) {
List<Pet> filteredPetList = new ArrayList<>();
for (Pet pet : petList) {
if (pet.getAgeMonths() > age) {
filteredPetList.add(pet);
}
}
return filteredPetList;
}
• You can now call this method as follows.
List<Pet> petList01 = filterPetsByAge(petList, 12);
List<Pet> petList02 = filterPetsByAge(petList, 24);
Attempt 3: Filtering with every attribute
• Ugly attempt of merging all attributes appears as follows.
10
public static List<Pet> filterPets(List<Pet> petList, String category, int age,
boolean flag) {
List<Pet> filteredPetList = new ArrayList<>();
for (Pet pet : petList) {
if ((flag && pet.getCategory().equals(category)) ||
(!flag && pet.getAgeMonths() > age)) {
filteredPetList.add(pet);
}
}
return filteredPetList;
}• You can now call this method as follows. This is extremely
bad!!!List<Pet> petList01 = filterPets(petList, "cat", 0, true);
List<Pet> petList02 = filterPets(petList, "", 12, false);
Behaviour Parameterization...
• How can we model the filtering criteria properly to cope with
the changing requirements?
• This criteria returns a boolean for the given list of pets.
• What if we define an interface to model the selection criteria.
11
public interface PetFilter {
boolean test(Pet pet);
}
• Now we can easily come up with multiple implementations
as follows.
public class OlderPetFilter implements PetFilter{
@Override
public boolean filter(Pet pet) {
return pet.getAgeMonths() > 12;
}
}
Attempt 4: Filtering by abstract criteria
• Modified filter method, which uses a PetFilter,
12
public static List<Pet> filterPets(List<Pet> petList, PetFilter filter) {
List<Pet> filteredPetList = new ArrayList<>();
for (Pet pet : petList) {
if (filter.test(pet)) {
filteredPetList.add(pet);
}
}
return filteredPetList;
}
• Now the behaviour of the filterPets method depends on the
code you pass to it via PetFilter object.
• I.e. We’ve parameterized the behaviour of the filterPets
method.
Tackling verbosity
• Consider the following PetFilter. Here we are interested in
only the return statement. All other lines are boilerplate code
which contribute to verbosity.
13
public class OlderPetFilter implements PetFilter{
@Override
public boolean filter(Pet pet) {
return pet.getAgeMonths() > 12;
}
}
• When you want to pass new behaviour to filterPets method,
you’re forced to declare classes that implement the PetFilter
interface.
• This is unnecessary overhead; can we do better?
Attempt 5: Using an anonymous class
• Anonymous classes allow you to declare and instantiate a
class at the same time.
• Don’t have a name.
• Allow you to create ad-hoc implementations.
• Parameterizing the behaviour of the method filterPets directly
inline.
14
List<Pet> filteredPetList = filterPets(petList, new PetFilter() {
@Override
public boolean test(Pet pet) {
return "cat".equals(pet.getCategory());
}
});
• Anonymous classes are still not good enough,
• first, they tend to be very bulky because they take a lot of
space,
• second, many programmers find them confusing to use.
Attempt 6: Using a lambda expression
• The previous code can be rewritten as follows in Java 8
using a lambda expression:
List<Pet> filteredPetList = filterPets(petList, (Pet pet) -> "cat".equals(pet.getCategory()));
• This codes looks a lot cleaner than the previous attempt
15
Sorting with a Comparator
Using an anonymous class,
16
petList.sort(new Comparator<Pet>() {
@Override
public int compare(Pet p1, Pet p2) {
return p1.getAgeMonths() - p2.getAgeMonths();
}
});
With lambda expression,
petList.sort((Pet p1, Pet p2) -> p1.getAgeMonths() - p2.getAgeMonths());
Lambda Expressions
17
Lambdas in a nutshell
• Anonymous
• We say anonymous because it doesn’t have an explicit name like a method would
normally have: less to write and think about!
• Function
• We say function because lambda isn’t associated with a particular class like a method is.
But like a method, a lambda has a list of parameters, a boy, a return type, and a possible
list of exceptions that can be thrown.
• Passed around
• A lambda expression can be passed as argument to a method or stored in a variable.
• Concise
• You don’t need to write a lot of boilerplate like you do for anonymous classes.
18
(Pet p1, Pet p2) -> p1.getAgeMonths() - p2.getAgeMonths();
Lambda
parameters
Lambda
body
Arrow
Lambda expressions
19
Before:
petList.sort(new Comparator<Pet>() {
@Override
public int compare(Pet p1, Pet p2) {
return p1.getAgeMonths() - p2.getAgeMonths();
}
});
After (with lambda expressions)
petList.sort((Pet p1, Pet p2) -> p1.getAgeMonths() - p2.getAgeMonths());
Lambda expressions...
20
This lambda expression has three parts,
1. A list of parameters
In this case it mirrors the parameters of the compare method of a
Comparator.
2. An arrow
The arrow -> separates the list of parameters from the body of the
lambda.
3. The body of the lambda
Compare two Pets using their age in months. The expression is
considered the lambda’s return value.
Valid lambda expressions in Java 8
21
// 1) This expression has one parameter of type String and returns an int. The lambda doesn't have a return statement here because the return
is implied
(String s) -> s.length();
// 2) This expression has one parameter of type Pet and returns a boolean.
(Pet p) -> p.getAgeMonths() > 15;
// 3) This expression has two parameters of type int with no return (void return). Note that lambda expressions can contain multiple
statements, in this case two.
(int x, int y) -> {
System.out.println("Result:");
System.out.println(x + y);
};
// 4) This expression has no parameter and return an int.
() -> 42;
// 5) This expression has two parameters of type Pet and returns an int.
(Pet p1, Pet p2) -> p1.getAgeMonths() > p2.getAgeMonths();
Syntax of a lambda
The basic syntax of a lambda is either,
(parameters) -> expression
or (note the curly braces for statements)
(parameters) -> { statements;}
22
Examples of lambdas
23
Use case Examples of lambdas
A boolean expression (List<String> list) -> list.isEmpty()
Creating objects () -> new Pet(“cat”, “13”)
Consuming from an object (Pet p) -> {
System.out.println(p.getAgeMonths());
}
Select/extract from an object (String s) -> s.length()
Combine two values (int a, int b) -> a*b
Compare two values (Pet p1, Pet p2) ->
p1.getAgeMonths() - p2.getAgeMonths()
Where and how to use lambdas
• Here we can assign a lambda to a variable and also we can
pass a lambda to the filter method.
• So where exactly can you use lambdas?
24
Predicate<Pet> petPredicate = (Pet pet) -> "cat".equals(pet.getCategory());
List<Pet> filteredPets = filter(petList, petPredicate);
• You can use a lambda in the context of a functional
interface.
• Here filter method expects a Predicate<T>, which is a
functional interface.
• So what are functional interfaces?
Functional interface
• A functional interface is an interface that specifies exactly
one abstract method.
25
// java.util.Comparator
public interface Comparator<T> {
int compare(T o1, T 02);
}
// java.util.Runnable
public interface Runnable {
void run();
}
// java.util.Callable
public interface Callable<V> {
V call();
}
• Lambda expressions let you
provide the implementation of
the abstract method of
functional interface directly
inline.
• Expression can be treated as
an instance of a functional
interface.
@FunctionalInterface
• Function interfaces in the new Java API are annotated with
@FunctionalInterface.
• This new annotation is indicates that the interface is intended
to be a functional interface.
• Compiler will throw error if the annotated interface is not a
functional interface.
• This annotation is not mandatory, but it’s a good practise to
use it.
26
The execute around pattern
• A recurrent pattern in resource processing is to open a
resource, do some processing, and then close the resource.
• The setup and cleanup phases are always similar and
surround the important code doing the processing
• This is called the execute around pattern.
27
public static String processFile() throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader("pets.txt"))) {
return br.readLine();
}
}
Type inference...
• Now you can omit the types of the parameters from a lambda
expression
28
Comparator<Pet> p = (Pet p1, Pet p2) -> p1.getAgeMonths() - p2.getAgeMonths();
Comparator<Pet> p = (p1, p2) -> p1.getAgeMonths() - p2.getAgeMonths();
• With type inference
29
Streams API
Java Collections API - Limitations
• Collections is the most heavily used API in Java.
• Allows you to group and process data.
• Consider a collection of Pet objects in the PetStore sample.
• How would you group a list of Pet objects by category?
• How would you find the oldest Pet in the PetStore?
• How would you find the list of Cats who are older than 15
months.
• Collections API is far from perfect to manipulate data and achieve
above requirements.
• If you are to implement above requirements using Collections API,
then you need use iterators.
• It’s very hard to leverage multicore architectures with iterators
30
Imperative Style Programming
• Saying how to do something,
• In terms of sequences of actions to be taken.
• Mutability
• Too many moving parts
• Hard make the code concurrent.
31
Declarative Style Programming
• Focus not on how, but what to do,
• Expressive
• Concise
• Immutability
• Most databases let you specify database operations declaratively.
• E.g. consider the following SQL query
32
SELECT category, ageInMonths FROM Pets WHERE ageInMonths > 15
• Here you don’t specify how to filter data, instead you express only
you what you expect.
• Can’t do we something similar with Collections?
Streams
• Streams are an update to Java API that lets you manipulate
collections of data in a declarative way.
• You express a query rather than code
• Stream can be processed in parallel transparently
• You don’t need to write any multithreaded code.
33
Java 7
34
// 1) Filter the elements using and accumulator
List<Pet> youngPetList = new ArrayList<>();
for (Pet pet : petList) {
if (pet.getAgeMonths() < 15) {
youngPetList.add(pet);
}
}
// 2) Sort the pets with an anonymous class.
Collections.sort(youngPetList, new Comparator<Pet>() {
@Override
public int compare(Pet pet1, Pet pet2) {
return Integer.compare(pet1.getAgeMonths(), pet2.getAgeMonths());
}
});
// 3) Process the sorted list to select the names of dishes
List<String> youngPetNames = new ArrayList<>();
for (Pet pet : youngPetList) {
youngPetNames.add(pet.getName());
}
Java 8
35
List<String> youngPetNames =
petList.stream()
.filter(pet -> pet.getAgeMonths() < 15)
.sorted(Comparator.comparing(Pet::getAgeMonths))
.map(pet -> pet.getName())
.collect(Collectors.toList());
// This exploits a multicore architecture and execute this code in parallel.
List<String> youngPetNames =
petList.parallelStream()
.filter(pet -> pet.getAgeMonths() < 15)
.sorted(Comparator.comparing(Pet::getAgeMonths))
.map(pet -> pet.getName())
.collect(Collectors.toList());
• This code is written in a declarative way. You specify what you want to
achieve as opposed to specifying how to implement an operation.
• You chain together several building-block operations to express a
complicated data processing pipeline while keeping your code readable
and its intent is clear.
What is a Stream?
• A sequence of elements from a source that supports data
processing operations.
• Sequence of elements - Like a collection, a stream provides
an interface to a sequenced set of values of a specific type.
• Source - Streams consume from a data-provisioning source
such as collections, arrays, or I/O resources.
• Data processing operations - Supports database-like
operations and common operations from functional
programming languages.
• e.g. filter, map, reduce, find, match, sort etc.
36
Streams sample
37
List<String> youngPetNames =
//Get a stream from the pet list.
petList.stream()
// Filter pets who not older than 15 months.
.filter(pet -> pet.getAgeMonths() < 15)
// Sort the pets using their age.
.sorted(Comparator.comparing(Pet::getAgeMonths))
// Get the names of the pets.
.map(pet -> pet.getName())
// Select only the first three.
.limit(3)
// Store the resutls in another list.
.collect(Collectors.toList());
Streams sample...
38
Streams vs Collections
39
Stream operations...
40
41
Working with streams
Filtering and slicing
Filtering with a predicate
• filter method takes a Predicate (a function returning a boolean) and
returns a stream including all the elements that match the
predicate.
• E.g. You can create a vegetarian menu by filtering all the
vegetarian dishes from a menu.
42
List<Dish> vegetarianMenu =
menu.stream()
.filter(Dish::isVegetarian)
.collect(Collectors.toList());
Filtering unique elements
43
• distinct method returns a stream with unique elements.
• According to the implementations of the hashCode and equals
methods of the objects.
• Consider the following example which filters all even numbers from
a list and makes sure that there are no duplicates.
Filtering unique elements...
44
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream()
.filter(i -> i % 2 == 0)
.distinct()
.forEach(System.out::println);
Truncating a stream
45
• limit(n) method returns another stream that’s no longer than a
given size.
• If the stream is ordered, the first elements are returned up to a
maximum of n.
• Note that limit also works on unordered streams (e.g. if the
source is a Set).
• You shouldn’t assume any order on the result in this case.
• How would you create a List by selecting the first three dishes that
have more than 300 calories?
Truncating a stream...
46
List<Dish> dishes =
menu.stream()
.filter(dish -> dish.getCalories() > 300)
.limit(3)
.collect(Collectors.toList());
Skipping elements
47
• skip(n) method returns another stream that discards the first n
elements.
• If the stream has fewer elements than n, then an empty stream
is returned.
• For example, the following code skips the first two dishes that have
more than 300 calories and the return the rest.
menu.stream()
.filter(dish ->
dish.getCalories() > 300)
.skip(2)
.collect(Collectors.toList());
48
Working with streams
Mapping
Applying function to each elements
49
• map method takes a Function as an argument. This Function is
applied to each element, mapping it to new element.
• For example, in the following code you pass a method reference
Dish::getName to the map method to extract the names of the
dishes in the stream.
• Because the method getName returns a String, the stream
outputted by the map method is of type Stream<String>
List<String> dishNames =
menu.stream()
.map(Dish::getName)
.collect(Collectors.toList());
50
Working with streams
Building streams
Building streams
51
• Streams from values.
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);
// You can get an empty stream using the empty method as follow:
Stream<String> emptyStream = Stream.empty();
• Streams from arrays.
int[] numbers = {2, 3, 5, 7, 11, 13};
int sum = Arrays.stream(numbers).sum();
Building streams..
52
• Streams from files.
long uniqueWords = 0;
// Streams are autoclosable.
try (Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())) {
uniqueWords = lines
// Generate a stream of words
.flatMap(line -> Arrays.stream(line.split(" ")))
// Remove duplicates
.distinct()
// Count the number of unique words
.count();
} catch (IOException e) {
// Deal with the exception if one occurs when opening the file.
}
53
Default methods
Evolving APIs
• A Java interface groups related methods together into a contract
• Any class which implements this interface must provide an
implementation for each method defined by the interface.
• This causes a problem when library designers need to update an interface
to add a new method.
• Java 8 designers faced the exact same issue while introducing Streams
API, but somehow they have introduced many new methods to existing
APIs. For example,
• Collection.streamI()
• Collection.parallelStream()
• List.sort()
54
Evolving APIs...
55
API Version 01
• Consider the following Interface
public interface Resizable {
int getWidth();
int getHeight();
int setWidth(int width);
int setHeight(int height);
int setAbsoluteSize(int width, int height);
}
• Assume you are a library designer and you’ve included the above API in
one of your libraries.
• Also assume there are external developers who have introduced their own
implementations based on this API.
• Now what if you want to introduce another method to this interface.
Evolving APIs...
56
API Version 02
• Consider the following updated Interface
public interface Resizable {
int getWidth();
int getHeight();
int setWidth(int width);
int setHeight(int height);
int setAbsoluteSize(int width, int height);
int setRelativeSize(int wFactor, int hFactor);
}
• This change creates few problems for existing API users.
Default methods
57
• A new feature added in Java 8 to help evolve APIs in a
compatible way.
• An interface can now contain method signatures for which an
implementing class doesn’t provide an implementation.
• The implementation of a default method should there in the
interface itselfdefault void setRelativeSize(int wFactor, int hFactor) {
setAbsoluteSize(getWidth() / wFactor, getHeight() / hFactor);
}
• Default methods are used extensively in the Java 8 API.
Abstract classes vs. interfaces in Java 8
58
• What’s the difference between an abstract class and an
interface in Java 8? They both can contain abstract methods
and methods with a body.
1. A class can extend only from one abstract class, but a class
can implement multiple interfaces.
2. An abstract class can enforce a common state through
instance variables (fields). An interface cannot have instance
variables.
59
Default methods
Usage patterns for default methods
Optional methods
60
• There are methods in interfaces that we usually don’t
implement, we always leave them empty.
• When you design an API, now you can provide a default
implementation for such methods.
• So the concrete classes don’t need to explicitly provide
an empty implementation.
• This reduces boilerplate code.
Resolution rules
61
• What if a class implements two interfaces that have the same
default method signature? Which method is the class allowed
to use?
• Consider the following example.
Resolution rules...
62
public interface A {
default void hello() {
System.out.println("Hello from A");
}
}
public interface B {
default void hello() {
System.out.println("Hello from B");
}
}
public class C implements B, A {
public static void main(String[] args) {
// Which one gets printed
new C().hello();
}
}
Three resolution rules to know
63
• There are three rules to follow when a class inherits a method with the
same signature from multiple places
1. Classes always win. A method declaration in the class or a superclass
takes priority over and default method declaration.
2. Otherwise, sub-interfaces win: the method with the same signature in the
most specific default-providing interface is selected.
3. Finally, if the choice is still ambiguous, the class inheriting from multiple
interfaces has to explicitly select which default method implementation to
use by overriding it and calling the desired method explicitly.
64
Parallel data processing
Fork/join framework
Parallel streams
Spliterator
Fork/join framework
• An implementation of the ExecutorService interface
• Designed to recursively split a parallelizable task into smaller tasks, and
then combine the results of each subtasks.
• ExecutorService distributes those subtasks to worker threads in the
ForkJoinPool (thread pool).
• These subtasks need to implement RecursiveTasks<R> interface
• R is the type of the result produced by the tasks.
• RecursiveAction if the task returns no result.
• You only need to implement the following abstract method to define a
RecursiveTask
65
protected abstract R compute();
Fork/join framework...
66
Fork/join framework - sample
67
/**
* Extend {@code RecursiveTask} to create a task usable with the fork/join framework.
* Executing a parallel sum using the fork/join framework.
*/
public class ForkJoinSumCalculator extends RecursiveTask<Long> {
// The size of the array under which this task is no longer split into subtasks.
public static final long THRESHOLD = 10_000;
// The array of numbers to be summed.
private final long[] numbers;
// The initial and final positions of the portion of the array processed by this subtask.
private final int start;
private final int end;
// Public constructor used to create the main task
public ForkJoinSumCalculator(long[] numbers) {
this(numbers, 0, numbers.length);
}
// Private constructor used to recursively create subtasks of the main task.
private ForkJoinSumCalculator(long[] numbers, int start, int end) {
this.numbers = numbers;
this.start = start;
this.end = end;
}
Fork/join framework - sample
68
protected Long compute() {
// The size of the portion of the array summed by this task.
int length = end - start;
if (length <= THRESHOLD) {
// If the size if less than or equal to the threshold, compute the result sequentially.
return computeSequentially();
}
// Create a subtask to sum the first half of the array.
ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length / 2);
// Asynchronously execute the newly created subtask using the another
thread of the ForkJoinPool
leftTask.fork();
// Create a subtask to the sum the second half of the array.
ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length / 2, end);
// Execute this second subtask synchronously, potentially allowing further recursive splits.
Long rightResult = rightTask.compute();
// Read the result of the first subtask or wait for it if it isn't ready.
Long leftResult = leftTask.join();
// The result of this task is the combination of the two subtasks.
return leftResult + rightResult;
}
Fork/join framework - sample
69
// Simple algorithm calculating the result of a subtask when it's no longer divisible.
private long computeSequentially() {
long sum = 0;
for (int i = start; i < end; i++) {
sum += numbers[i];
}
return sum;
}
• Running the ForkJoinSumCalculator.
public static long forkJoinSum(long n) {
long[] numbers = LongStream.rangeClosed(1, n).toArray();
ForkJoinTask<Long> task = new ForkJoinSumCalculator(numbers);
return new ForkJoinPool().invoke(task);
}
Fork/join algorithm
70
Best practises for using the fork/join framework
71
• Invoke the join method on a task blocks the caller until the result produced
by that task is ready.
• The invoke method of a ForkJoinPool shouldn’t be used from within a
RecursiveTask.
• Calling the fork method on a subtask is the way to schedule it on the
ForkJoinPool.
ForkJoinPool
72
• As a best practise, don’t create ForkJoinPool more than once
in your application.
• Create is using the default no-argument constructor
• This allows the pool to use all the processors available to
the JVM.
• Calculates the number of threads based on the available
processors.
73
• Allows you to execute operations in parallel on a collection of data without
much effort.
• Allows you to declaratively turn a sequential stream into a parallel one.
• Uses the fork/join framework under the hood.
• A parallel stream is a stream that splits its elements into multiple chunks,
processing each chunks with a different thread.
• This should keep all your cores busy by equally partitioning chunks
• Suppose you need to write a method accepting a number n as an
argument and returning the sum of all the numbers from 1 to the given
amount. Let’s optimize this method step by step.
Parallel streams
74
• Using traditional java style.
Parallel streams...
public static long iterativeSum(long n) {
long result = 0;
for (long i = 0; i <= n; i++) {
result += i;
}
return result;
}
//Result
Iterative sum done in: 3 msecs
75
• Using infinite stream of numbers, limiting it to the passed number, and then
reduce the resulting stream with a BinaryOperator thats just sums two
numbers
Parallel streams...
public static long rangedSum(long n) {
return LongStream.rangeClosed(1, n)
.reduce(0L, Long::sum);
}
//Result
Sequential sum done in: 4 msecs
• Previous one runs faster because its works at a much lower level and,
more important, doesn’t need to perform any boxing or unboxing for
primitive values
76
Parallel streams...
77
• Turning the sequential stream into a parallel one.
Parallel streams...
public static long parallelRangedSum(long n) {
return LongStream.rangeClosed(1, n)
.parallel()
.reduce(0L, Long::sum);
}
//Result
Sequential sum done in: 1 msecs
• Here the difference is that the stream is internally divided into
multiple chunks. Reduction operation can work on the
various chunks independently and in parallel.
78
Parallel streams...
79
• How can we configure the thread pool size here?
• Parallel streams internally use the default ForkJoinPool
• This pool has as many threads as you have processors, as returned
by Runtime.getRuntime().availableProcessors().
• You can change the size of the ForkJoinPool using the following system
property.
Configuring the thread pool
System.setProperty(“java.util.concurrent.ForkJoinPool.common.parallelism”, 12)
• This is a global setting, so it will affect all the parallel streams in your code.
• The default value of this pool is equal to the number of processors on your
machine and it is a meaningful default.
• Don’t change it unless you have a very good reason for doing so.
80
• If in doubt, measure. Turning a sequential stream into a parallel one is
trivial but not always the right thing to do.
• Watch out for boxing. Automatic boxing and unboxing operations can
dramatically hurt performance.
• Some operations naturally perform worse on a parallel stream than on a
sequential stream. For example limit and findFirst vs. findAny
• Consider the total computational cost of the pipeline of operations
performed by the stream. With N being the number of elements to be
processed and Q the approximate cost of processing one of these
elements through the stream pipeline, the product of N*Q gives a rough
qualitative estimation of this cost. A higher value for Q implies a better
chance of good performance when using a parallel stream.
Using parallel streams effectively
81
• Code readability can be very subjective.
• Improve code readability means ensuring your code is understandable
and maintainable by people beside you.
• How Java 8 allows you to improve code readability?
• You can reduce the verbosity of your code, making it easier to
understand.
• You can improve the intent of your code by using method references
and the Streams API
• Following are three simple refactorings that use lambdas, method
references , and streams
• Refactoring anonymous classes to lambda expressions
• Refactoring lambda expressions to method references
• Refactoring imperative-style data processing to streams.
Improving code readability
82
• Try to convert anonymous classes implementing one single
abstract method to lambda expressions.
• But sometime, you may get into issues
• The meanings of this and super are different from
anonymous classes and lambda expressions.
• Inside an anonymous class, this refers to the anonymous
class itself, but inside a lambda it refers to the enclosing
class.
• Anonymous classes are allowed to shadow variables
from the enclosing class. Lambda expressions can’t do
that.
From anonymous classes to
lambdas
83
From anonymous classes to
lambdas...
84
• Converting an anonymous class to a lambda expression can make the
resulting code ambiguous in the context of overloading.
• The type of the anonymous class is explicit at instantiation.
• But, the type of the lambda depends on its context.
From anonymous classes to lambdas...
• You can now pass an anonymous class implementing Task without a
problem.
85
• But converting the previous anonymous class to a lambda results in an
ambiguous method call, because both Runnable and Task are valid target
types.
From anonymous classes to lambdas...
• You can solve the ambiguity by the providing an explicit cast.
86
Best practises
List <String> myList = …;
if (myList.size > 0) { … }
if myList.isEmpty() { … }
87
Best practises
Returning Empty Collections instead of Null
public static List<Pet> getAllPets(){
List<Pet> lPets = new ArrayList()<Pet>();
................
return lPets;
}
88
Best practises
Avoid unnecessary Objects
public static List<Pet> getAllPets(){
List<Pet> lPets = null;
//if throw exception etc
................
if (lPets == null) {
lPets = new ArrayList()<Pet>();
}
................
return lPets;
}
//Slower Instantiation
String bad = new String("Yet another string object");
//Faster Instantiation
String good = "Yet another string object";
89
Best practises
Dilemma between Array and ArrayList
• Arrays have fixed size but ArrayLists have variable sizes. Since the size of
Array is fixed, the memory gets allocated at the time of declaration of Array
type variable. Hence, Arrays are very fast. On the other hand, if we are not
aware of the size of the data, then ArrayList is More data will lead to
ArrayOutOfBoundException and less data will cause wastage of storage
space.
• It is much easier to Add or Remove elements from ArrayList than Array
• Array can be multi-dimensional but ArrayList can be only one dimension.
90
Best practises
Difference between single quotes and double quotes
public static void main (String [] args) {
System.out.println("H" + "I");
System.out.println('H' + 'I');
}
91
Best practises
Choice between Float and Double
45.123456…?
Most processors take nearly the same amount of processing time to perform operations on
Float and Double. Double offers far more precision in the same amount of computation time.
CONTACT US !

More Related Content

What's hot

Array vs array list
Array vs array listArray vs array list
Array vs array listRavi Shetye
 
Kotlin Collections
Kotlin CollectionsKotlin Collections
Kotlin CollectionsHalil Özcan
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!Jakub Kubrynski
 
Postgresql Database Administration- Day3
Postgresql Database Administration- Day3Postgresql Database Administration- Day3
Postgresql Database Administration- Day3PoguttuezhiniVP
 
Swagger / Quick Start Guide
Swagger / Quick Start GuideSwagger / Quick Start Guide
Swagger / Quick Start GuideAndrii Gakhov
 
Force.com canvas入門ガイド
Force.com canvas入門ガイドForce.com canvas入門ガイド
Force.com canvas入門ガイドKazuki Nakajima
 
Clean code in JavaScript
Clean code in JavaScriptClean code in JavaScript
Clean code in JavaScriptMathieu Breton
 
Mysql creating stored function
Mysql  creating stored function Mysql  creating stored function
Mysql creating stored function Prof.Nilesh Magar
 
Celery - A Distributed Task Queue
Celery - A Distributed Task QueueCelery - A Distributed Task Queue
Celery - A Distributed Task QueueDuy Do
 
Morel, a Functional Query Language
Morel, a Functional Query LanguageMorel, a Functional Query Language
Morel, a Functional Query LanguageJulian Hyde
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsSalesforce Developers
 
DevOps with ActiveMQ, Camel, Fabric8, and HawtIO
DevOps with ActiveMQ, Camel, Fabric8, and HawtIO DevOps with ActiveMQ, Camel, Fabric8, and HawtIO
DevOps with ActiveMQ, Camel, Fabric8, and HawtIO Christian Posta
 
Spring Boot & Actuators
Spring Boot & ActuatorsSpring Boot & Actuators
Spring Boot & ActuatorsVMware Tanzu
 

What's hot (20)

Array vs array list
Array vs array listArray vs array list
Array vs array list
 
Celery
CeleryCelery
Celery
 
Kotlin Collections
Kotlin CollectionsKotlin Collections
Kotlin Collections
 
View & index in SQL
View & index in SQLView & index in SQL
View & index in SQL
 
Kong
KongKong
Kong
 
Web API Basics
Web API BasicsWeb API Basics
Web API Basics
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
 
Postgresql Database Administration- Day3
Postgresql Database Administration- Day3Postgresql Database Administration- Day3
Postgresql Database Administration- Day3
 
Swagger / Quick Start Guide
Swagger / Quick Start GuideSwagger / Quick Start Guide
Swagger / Quick Start Guide
 
Force.com canvas入門ガイド
Force.com canvas入門ガイドForce.com canvas入門ガイド
Force.com canvas入門ガイド
 
Angular 2 observables
Angular 2 observablesAngular 2 observables
Angular 2 observables
 
Clean code in JavaScript
Clean code in JavaScriptClean code in JavaScript
Clean code in JavaScript
 
Mysql creating stored function
Mysql  creating stored function Mysql  creating stored function
Mysql creating stored function
 
Introduction to spring boot
Introduction to spring bootIntroduction to spring boot
Introduction to spring boot
 
Celery - A Distributed Task Queue
Celery - A Distributed Task QueueCelery - A Distributed Task Queue
Celery - A Distributed Task Queue
 
Morel, a Functional Query Language
Morel, a Functional Query LanguageMorel, a Functional Query Language
Morel, a Functional Query Language
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong Foundations
 
SQL JOINS
SQL JOINSSQL JOINS
SQL JOINS
 
DevOps with ActiveMQ, Camel, Fabric8, and HawtIO
DevOps with ActiveMQ, Camel, Fabric8, and HawtIO DevOps with ActiveMQ, Camel, Fabric8, and HawtIO
DevOps with ActiveMQ, Camel, Fabric8, and HawtIO
 
Spring Boot & Actuators
Spring Boot & ActuatorsSpring Boot & Actuators
Spring Boot & Actuators
 

Similar to Java 8 ​and ​Best Practices

Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Codemotion
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalUrs Peter
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8Martin Toshev
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streamsjessitron
 
Assg 07 Templates and Operator OverloadingCOSC 2336 Sprin.docx
Assg 07 Templates and Operator OverloadingCOSC 2336 Sprin.docxAssg 07 Templates and Operator OverloadingCOSC 2336 Sprin.docx
Assg 07 Templates and Operator OverloadingCOSC 2336 Sprin.docxfestockton
 
A brief tour of modern Java
A brief tour of modern JavaA brief tour of modern Java
A brief tour of modern JavaSina Madani
 

Similar to Java 8 ​and ​Best Practices (20)

Java8
Java8Java8
Java8
 
Java 8 Intro - Core Features
Java 8 Intro - Core FeaturesJava 8 Intro - Core Features
Java 8 Intro - Core Features
 
java8
java8java8
java8
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018
 
Lazy java
Lazy javaLazy java
Lazy java
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
 
Java 8 new features
Java 8 new featuresJava 8 new features
Java 8 new features
 
Lambdas in Java 8
Lambdas in Java 8Lambdas in Java 8
Lambdas in Java 8
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_final
 
Java 8 Feature Preview
Java 8 Feature PreviewJava 8 Feature Preview
Java 8 Feature Preview
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Java 8 streams
Java 8 streamsJava 8 streams
Java 8 streams
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streams
 
Assg 07 Templates and Operator OverloadingCOSC 2336 Sprin.docx
Assg 07 Templates and Operator OverloadingCOSC 2336 Sprin.docxAssg 07 Templates and Operator OverloadingCOSC 2336 Sprin.docx
Assg 07 Templates and Operator OverloadingCOSC 2336 Sprin.docx
 
A brief tour of modern Java
A brief tour of modern JavaA brief tour of modern Java
A brief tour of modern Java
 

More from WSO2

Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessWSO2
 
How to Create a Service in Choreo
How to Create a Service in ChoreoHow to Create a Service in Choreo
How to Create a Service in ChoreoWSO2
 
Ballerina Tech Talk - May 2023
Ballerina Tech Talk - May 2023Ballerina Tech Talk - May 2023
Ballerina Tech Talk - May 2023WSO2
 
Platform Strategy to Deliver Digital Experiences on Azure
Platform Strategy to Deliver Digital Experiences on AzurePlatform Strategy to Deliver Digital Experiences on Azure
Platform Strategy to Deliver Digital Experiences on AzureWSO2
 
GartnerITSymSessionSlides.pdf
GartnerITSymSessionSlides.pdfGartnerITSymSessionSlides.pdf
GartnerITSymSessionSlides.pdfWSO2
 
[Webinar] How to Create an API in Minutes
[Webinar] How to Create an API in Minutes[Webinar] How to Create an API in Minutes
[Webinar] How to Create an API in MinutesWSO2
 
Modernizing the Student Journey with Ethos Identity
Modernizing the Student Journey with Ethos IdentityModernizing the Student Journey with Ethos Identity
Modernizing the Student Journey with Ethos IdentityWSO2
 
Choreo - Build unique digital experiences on WSO2's platform, secured by Etho...
Choreo - Build unique digital experiences on WSO2's platform, secured by Etho...Choreo - Build unique digital experiences on WSO2's platform, secured by Etho...
Choreo - Build unique digital experiences on WSO2's platform, secured by Etho...WSO2
 
CIO Summit Berlin 2022.pptx.pdf
CIO Summit Berlin 2022.pptx.pdfCIO Summit Berlin 2022.pptx.pdf
CIO Summit Berlin 2022.pptx.pdfWSO2
 
Delivering New Digital Experiences Fast - Introducing Choreo
Delivering New Digital Experiences Fast - Introducing ChoreoDelivering New Digital Experiences Fast - Introducing Choreo
Delivering New Digital Experiences Fast - Introducing ChoreoWSO2
 
Fueling the Digital Experience Economy with Connected Products
Fueling the Digital Experience Economy with Connected ProductsFueling the Digital Experience Economy with Connected Products
Fueling the Digital Experience Economy with Connected ProductsWSO2
 
A Reference Methodology for Agile Digital Businesses
 A Reference Methodology for Agile Digital Businesses A Reference Methodology for Agile Digital Businesses
A Reference Methodology for Agile Digital BusinessesWSO2
 
Workflows in WSO2 API Manager - WSO2 API Manager Community Call (12/15/2021)
Workflows in WSO2 API Manager - WSO2 API Manager Community Call (12/15/2021)Workflows in WSO2 API Manager - WSO2 API Manager Community Call (12/15/2021)
Workflows in WSO2 API Manager - WSO2 API Manager Community Call (12/15/2021)WSO2
 
Lessons from the pandemic - From a single use case to true transformation
 Lessons from the pandemic - From a single use case to true transformation Lessons from the pandemic - From a single use case to true transformation
Lessons from the pandemic - From a single use case to true transformationWSO2
 
Adding Liveliness to Banking Experiences
Adding Liveliness to Banking ExperiencesAdding Liveliness to Banking Experiences
Adding Liveliness to Banking ExperiencesWSO2
 
Building a Future-ready Bank
Building a Future-ready BankBuilding a Future-ready Bank
Building a Future-ready BankWSO2
 
WSO2 API Manager Community Call - November 2021
WSO2 API Manager Community Call - November 2021WSO2 API Manager Community Call - November 2021
WSO2 API Manager Community Call - November 2021WSO2
 
[API World ] - Managing Asynchronous APIs
[API World ] - Managing Asynchronous APIs[API World ] - Managing Asynchronous APIs
[API World ] - Managing Asynchronous APIsWSO2
 
[API World 2021 ] - Understanding Cloud Native Deployment
[API World 2021 ] - Understanding Cloud Native Deployment[API World 2021 ] - Understanding Cloud Native Deployment
[API World 2021 ] - Understanding Cloud Native DeploymentWSO2
 
[API Word 2021] - Quantum Duality of “API as a Business and a Technology”
[API Word 2021] - Quantum Duality of “API as a Business and a Technology”[API Word 2021] - Quantum Duality of “API as a Business and a Technology”
[API Word 2021] - Quantum Duality of “API as a Business and a Technology”WSO2
 

More from WSO2 (20)

Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with Platformless
 
How to Create a Service in Choreo
How to Create a Service in ChoreoHow to Create a Service in Choreo
How to Create a Service in Choreo
 
Ballerina Tech Talk - May 2023
Ballerina Tech Talk - May 2023Ballerina Tech Talk - May 2023
Ballerina Tech Talk - May 2023
 
Platform Strategy to Deliver Digital Experiences on Azure
Platform Strategy to Deliver Digital Experiences on AzurePlatform Strategy to Deliver Digital Experiences on Azure
Platform Strategy to Deliver Digital Experiences on Azure
 
GartnerITSymSessionSlides.pdf
GartnerITSymSessionSlides.pdfGartnerITSymSessionSlides.pdf
GartnerITSymSessionSlides.pdf
 
[Webinar] How to Create an API in Minutes
[Webinar] How to Create an API in Minutes[Webinar] How to Create an API in Minutes
[Webinar] How to Create an API in Minutes
 
Modernizing the Student Journey with Ethos Identity
Modernizing the Student Journey with Ethos IdentityModernizing the Student Journey with Ethos Identity
Modernizing the Student Journey with Ethos Identity
 
Choreo - Build unique digital experiences on WSO2's platform, secured by Etho...
Choreo - Build unique digital experiences on WSO2's platform, secured by Etho...Choreo - Build unique digital experiences on WSO2's platform, secured by Etho...
Choreo - Build unique digital experiences on WSO2's platform, secured by Etho...
 
CIO Summit Berlin 2022.pptx.pdf
CIO Summit Berlin 2022.pptx.pdfCIO Summit Berlin 2022.pptx.pdf
CIO Summit Berlin 2022.pptx.pdf
 
Delivering New Digital Experiences Fast - Introducing Choreo
Delivering New Digital Experiences Fast - Introducing ChoreoDelivering New Digital Experiences Fast - Introducing Choreo
Delivering New Digital Experiences Fast - Introducing Choreo
 
Fueling the Digital Experience Economy with Connected Products
Fueling the Digital Experience Economy with Connected ProductsFueling the Digital Experience Economy with Connected Products
Fueling the Digital Experience Economy with Connected Products
 
A Reference Methodology for Agile Digital Businesses
 A Reference Methodology for Agile Digital Businesses A Reference Methodology for Agile Digital Businesses
A Reference Methodology for Agile Digital Businesses
 
Workflows in WSO2 API Manager - WSO2 API Manager Community Call (12/15/2021)
Workflows in WSO2 API Manager - WSO2 API Manager Community Call (12/15/2021)Workflows in WSO2 API Manager - WSO2 API Manager Community Call (12/15/2021)
Workflows in WSO2 API Manager - WSO2 API Manager Community Call (12/15/2021)
 
Lessons from the pandemic - From a single use case to true transformation
 Lessons from the pandemic - From a single use case to true transformation Lessons from the pandemic - From a single use case to true transformation
Lessons from the pandemic - From a single use case to true transformation
 
Adding Liveliness to Banking Experiences
Adding Liveliness to Banking ExperiencesAdding Liveliness to Banking Experiences
Adding Liveliness to Banking Experiences
 
Building a Future-ready Bank
Building a Future-ready BankBuilding a Future-ready Bank
Building a Future-ready Bank
 
WSO2 API Manager Community Call - November 2021
WSO2 API Manager Community Call - November 2021WSO2 API Manager Community Call - November 2021
WSO2 API Manager Community Call - November 2021
 
[API World ] - Managing Asynchronous APIs
[API World ] - Managing Asynchronous APIs[API World ] - Managing Asynchronous APIs
[API World ] - Managing Asynchronous APIs
 
[API World 2021 ] - Understanding Cloud Native Deployment
[API World 2021 ] - Understanding Cloud Native Deployment[API World 2021 ] - Understanding Cloud Native Deployment
[API World 2021 ] - Understanding Cloud Native Deployment
 
[API Word 2021] - Quantum Duality of “API as a Business and a Technology”
[API Word 2021] - Quantum Duality of “API as a Business and a Technology”[API Word 2021] - Quantum Duality of “API as a Business and a Technology”
[API Word 2021] - Quantum Duality of “API as a Business and a Technology”
 

Recently uploaded

Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 

Recently uploaded (20)

Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 

Java 8 ​and ​Best Practices

  • 1. Jaffna Meetup 04 JAVA 8 Brought to you by WSO2 November 2016 1
  • 2. Reference book • Based on training done by Sameera Jayasoma (Associate Director/Architect @ wso2) • I’ve used the book “Java 8 In Action” as the reference book. • You can get all the sample sources from here. 2
  • 3. What’s new in Java 8? • Lambda Expressions • Default Methods • Method references • Type Annotations and Pluggable Type Systems • Repeating Annotations • Method Parameter Reflection. • Security Enhancements. • Streams/Parallel Streams • Optional • Nashorn • New Date and Time API • No more permanent Generation 3
  • 4. Why Java 8? • More concise code • Simpler use of multicore processors • No official support for previous versions 4
  • 6. Functions as Values in Java 8 • Java 8 now treats Functions, or in other words methods as first-class citizens. • Java used to treat primitives and object as first-class citizens. • This allows us to pass methods around at runtime. This proved to be very useful in other functional languages. 6
  • 7. Behaviour Parameterization • Is a software development pattern • easy to handle software requirement changes. • Allows a block of code to be executed later • You can pass this block of code as an argument to a method. • Now this method’s behaviour depends on the behaviour of this block of code. • This is called behaviour parameterization. • Consider a pet store. How do you filter out all the cats from the pet store? 7
  • 8. Attempt 1: Filtering Cats • A first solution would look like following. 8 public static List<Pet> filterCats(List<Pet> petList) { List<Pet> catList = new ArrayList<>(); for (Pet pet : petList) { if ("cat".equals(pet.getCategory())) { catList.add(pet); } } return catList; } • But now you need to filter pets who are more than 12 months older? • What would you do? • Introduce another duplicate method?
  • 9. Attempt 2: Parameterizing the age • You can parameterize the age and be more flexible to such changes 9 public static List<Pet> filterPetsByAge(List<Pet> petList, int age) { List<Pet> filteredPetList = new ArrayList<>(); for (Pet pet : petList) { if (pet.getAgeMonths() > age) { filteredPetList.add(pet); } } return filteredPetList; } • You can now call this method as follows. List<Pet> petList01 = filterPetsByAge(petList, 12); List<Pet> petList02 = filterPetsByAge(petList, 24);
  • 10. Attempt 3: Filtering with every attribute • Ugly attempt of merging all attributes appears as follows. 10 public static List<Pet> filterPets(List<Pet> petList, String category, int age, boolean flag) { List<Pet> filteredPetList = new ArrayList<>(); for (Pet pet : petList) { if ((flag && pet.getCategory().equals(category)) || (!flag && pet.getAgeMonths() > age)) { filteredPetList.add(pet); } } return filteredPetList; }• You can now call this method as follows. This is extremely bad!!!List<Pet> petList01 = filterPets(petList, "cat", 0, true); List<Pet> petList02 = filterPets(petList, "", 12, false);
  • 11. Behaviour Parameterization... • How can we model the filtering criteria properly to cope with the changing requirements? • This criteria returns a boolean for the given list of pets. • What if we define an interface to model the selection criteria. 11 public interface PetFilter { boolean test(Pet pet); } • Now we can easily come up with multiple implementations as follows. public class OlderPetFilter implements PetFilter{ @Override public boolean filter(Pet pet) { return pet.getAgeMonths() > 12; } }
  • 12. Attempt 4: Filtering by abstract criteria • Modified filter method, which uses a PetFilter, 12 public static List<Pet> filterPets(List<Pet> petList, PetFilter filter) { List<Pet> filteredPetList = new ArrayList<>(); for (Pet pet : petList) { if (filter.test(pet)) { filteredPetList.add(pet); } } return filteredPetList; } • Now the behaviour of the filterPets method depends on the code you pass to it via PetFilter object. • I.e. We’ve parameterized the behaviour of the filterPets method.
  • 13. Tackling verbosity • Consider the following PetFilter. Here we are interested in only the return statement. All other lines are boilerplate code which contribute to verbosity. 13 public class OlderPetFilter implements PetFilter{ @Override public boolean filter(Pet pet) { return pet.getAgeMonths() > 12; } } • When you want to pass new behaviour to filterPets method, you’re forced to declare classes that implement the PetFilter interface. • This is unnecessary overhead; can we do better?
  • 14. Attempt 5: Using an anonymous class • Anonymous classes allow you to declare and instantiate a class at the same time. • Don’t have a name. • Allow you to create ad-hoc implementations. • Parameterizing the behaviour of the method filterPets directly inline. 14 List<Pet> filteredPetList = filterPets(petList, new PetFilter() { @Override public boolean test(Pet pet) { return "cat".equals(pet.getCategory()); } }); • Anonymous classes are still not good enough, • first, they tend to be very bulky because they take a lot of space, • second, many programmers find them confusing to use.
  • 15. Attempt 6: Using a lambda expression • The previous code can be rewritten as follows in Java 8 using a lambda expression: List<Pet> filteredPetList = filterPets(petList, (Pet pet) -> "cat".equals(pet.getCategory())); • This codes looks a lot cleaner than the previous attempt 15
  • 16. Sorting with a Comparator Using an anonymous class, 16 petList.sort(new Comparator<Pet>() { @Override public int compare(Pet p1, Pet p2) { return p1.getAgeMonths() - p2.getAgeMonths(); } }); With lambda expression, petList.sort((Pet p1, Pet p2) -> p1.getAgeMonths() - p2.getAgeMonths());
  • 18. Lambdas in a nutshell • Anonymous • We say anonymous because it doesn’t have an explicit name like a method would normally have: less to write and think about! • Function • We say function because lambda isn’t associated with a particular class like a method is. But like a method, a lambda has a list of parameters, a boy, a return type, and a possible list of exceptions that can be thrown. • Passed around • A lambda expression can be passed as argument to a method or stored in a variable. • Concise • You don’t need to write a lot of boilerplate like you do for anonymous classes. 18 (Pet p1, Pet p2) -> p1.getAgeMonths() - p2.getAgeMonths(); Lambda parameters Lambda body Arrow
  • 19. Lambda expressions 19 Before: petList.sort(new Comparator<Pet>() { @Override public int compare(Pet p1, Pet p2) { return p1.getAgeMonths() - p2.getAgeMonths(); } }); After (with lambda expressions) petList.sort((Pet p1, Pet p2) -> p1.getAgeMonths() - p2.getAgeMonths());
  • 20. Lambda expressions... 20 This lambda expression has three parts, 1. A list of parameters In this case it mirrors the parameters of the compare method of a Comparator. 2. An arrow The arrow -> separates the list of parameters from the body of the lambda. 3. The body of the lambda Compare two Pets using their age in months. The expression is considered the lambda’s return value.
  • 21. Valid lambda expressions in Java 8 21 // 1) This expression has one parameter of type String and returns an int. The lambda doesn't have a return statement here because the return is implied (String s) -> s.length(); // 2) This expression has one parameter of type Pet and returns a boolean. (Pet p) -> p.getAgeMonths() > 15; // 3) This expression has two parameters of type int with no return (void return). Note that lambda expressions can contain multiple statements, in this case two. (int x, int y) -> { System.out.println("Result:"); System.out.println(x + y); }; // 4) This expression has no parameter and return an int. () -> 42; // 5) This expression has two parameters of type Pet and returns an int. (Pet p1, Pet p2) -> p1.getAgeMonths() > p2.getAgeMonths();
  • 22. Syntax of a lambda The basic syntax of a lambda is either, (parameters) -> expression or (note the curly braces for statements) (parameters) -> { statements;} 22
  • 23. Examples of lambdas 23 Use case Examples of lambdas A boolean expression (List<String> list) -> list.isEmpty() Creating objects () -> new Pet(“cat”, “13”) Consuming from an object (Pet p) -> { System.out.println(p.getAgeMonths()); } Select/extract from an object (String s) -> s.length() Combine two values (int a, int b) -> a*b Compare two values (Pet p1, Pet p2) -> p1.getAgeMonths() - p2.getAgeMonths()
  • 24. Where and how to use lambdas • Here we can assign a lambda to a variable and also we can pass a lambda to the filter method. • So where exactly can you use lambdas? 24 Predicate<Pet> petPredicate = (Pet pet) -> "cat".equals(pet.getCategory()); List<Pet> filteredPets = filter(petList, petPredicate); • You can use a lambda in the context of a functional interface. • Here filter method expects a Predicate<T>, which is a functional interface. • So what are functional interfaces?
  • 25. Functional interface • A functional interface is an interface that specifies exactly one abstract method. 25 // java.util.Comparator public interface Comparator<T> { int compare(T o1, T 02); } // java.util.Runnable public interface Runnable { void run(); } // java.util.Callable public interface Callable<V> { V call(); } • Lambda expressions let you provide the implementation of the abstract method of functional interface directly inline. • Expression can be treated as an instance of a functional interface.
  • 26. @FunctionalInterface • Function interfaces in the new Java API are annotated with @FunctionalInterface. • This new annotation is indicates that the interface is intended to be a functional interface. • Compiler will throw error if the annotated interface is not a functional interface. • This annotation is not mandatory, but it’s a good practise to use it. 26
  • 27. The execute around pattern • A recurrent pattern in resource processing is to open a resource, do some processing, and then close the resource. • The setup and cleanup phases are always similar and surround the important code doing the processing • This is called the execute around pattern. 27 public static String processFile() throws IOException { try (BufferedReader br = new BufferedReader(new FileReader("pets.txt"))) { return br.readLine(); } }
  • 28. Type inference... • Now you can omit the types of the parameters from a lambda expression 28 Comparator<Pet> p = (Pet p1, Pet p2) -> p1.getAgeMonths() - p2.getAgeMonths(); Comparator<Pet> p = (p1, p2) -> p1.getAgeMonths() - p2.getAgeMonths(); • With type inference
  • 30. Java Collections API - Limitations • Collections is the most heavily used API in Java. • Allows you to group and process data. • Consider a collection of Pet objects in the PetStore sample. • How would you group a list of Pet objects by category? • How would you find the oldest Pet in the PetStore? • How would you find the list of Cats who are older than 15 months. • Collections API is far from perfect to manipulate data and achieve above requirements. • If you are to implement above requirements using Collections API, then you need use iterators. • It’s very hard to leverage multicore architectures with iterators 30
  • 31. Imperative Style Programming • Saying how to do something, • In terms of sequences of actions to be taken. • Mutability • Too many moving parts • Hard make the code concurrent. 31
  • 32. Declarative Style Programming • Focus not on how, but what to do, • Expressive • Concise • Immutability • Most databases let you specify database operations declaratively. • E.g. consider the following SQL query 32 SELECT category, ageInMonths FROM Pets WHERE ageInMonths > 15 • Here you don’t specify how to filter data, instead you express only you what you expect. • Can’t do we something similar with Collections?
  • 33. Streams • Streams are an update to Java API that lets you manipulate collections of data in a declarative way. • You express a query rather than code • Stream can be processed in parallel transparently • You don’t need to write any multithreaded code. 33
  • 34. Java 7 34 // 1) Filter the elements using and accumulator List<Pet> youngPetList = new ArrayList<>(); for (Pet pet : petList) { if (pet.getAgeMonths() < 15) { youngPetList.add(pet); } } // 2) Sort the pets with an anonymous class. Collections.sort(youngPetList, new Comparator<Pet>() { @Override public int compare(Pet pet1, Pet pet2) { return Integer.compare(pet1.getAgeMonths(), pet2.getAgeMonths()); } }); // 3) Process the sorted list to select the names of dishes List<String> youngPetNames = new ArrayList<>(); for (Pet pet : youngPetList) { youngPetNames.add(pet.getName()); }
  • 35. Java 8 35 List<String> youngPetNames = petList.stream() .filter(pet -> pet.getAgeMonths() < 15) .sorted(Comparator.comparing(Pet::getAgeMonths)) .map(pet -> pet.getName()) .collect(Collectors.toList()); // This exploits a multicore architecture and execute this code in parallel. List<String> youngPetNames = petList.parallelStream() .filter(pet -> pet.getAgeMonths() < 15) .sorted(Comparator.comparing(Pet::getAgeMonths)) .map(pet -> pet.getName()) .collect(Collectors.toList()); • This code is written in a declarative way. You specify what you want to achieve as opposed to specifying how to implement an operation. • You chain together several building-block operations to express a complicated data processing pipeline while keeping your code readable and its intent is clear.
  • 36. What is a Stream? • A sequence of elements from a source that supports data processing operations. • Sequence of elements - Like a collection, a stream provides an interface to a sequenced set of values of a specific type. • Source - Streams consume from a data-provisioning source such as collections, arrays, or I/O resources. • Data processing operations - Supports database-like operations and common operations from functional programming languages. • e.g. filter, map, reduce, find, match, sort etc. 36
  • 37. Streams sample 37 List<String> youngPetNames = //Get a stream from the pet list. petList.stream() // Filter pets who not older than 15 months. .filter(pet -> pet.getAgeMonths() < 15) // Sort the pets using their age. .sorted(Comparator.comparing(Pet::getAgeMonths)) // Get the names of the pets. .map(pet -> pet.getName()) // Select only the first three. .limit(3) // Store the resutls in another list. .collect(Collectors.toList());
  • 42. Filtering with a predicate • filter method takes a Predicate (a function returning a boolean) and returns a stream including all the elements that match the predicate. • E.g. You can create a vegetarian menu by filtering all the vegetarian dishes from a menu. 42 List<Dish> vegetarianMenu = menu.stream() .filter(Dish::isVegetarian) .collect(Collectors.toList());
  • 43. Filtering unique elements 43 • distinct method returns a stream with unique elements. • According to the implementations of the hashCode and equals methods of the objects. • Consider the following example which filters all even numbers from a list and makes sure that there are no duplicates.
  • 44. Filtering unique elements... 44 List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); numbers.stream() .filter(i -> i % 2 == 0) .distinct() .forEach(System.out::println);
  • 45. Truncating a stream 45 • limit(n) method returns another stream that’s no longer than a given size. • If the stream is ordered, the first elements are returned up to a maximum of n. • Note that limit also works on unordered streams (e.g. if the source is a Set). • You shouldn’t assume any order on the result in this case. • How would you create a List by selecting the first three dishes that have more than 300 calories?
  • 46. Truncating a stream... 46 List<Dish> dishes = menu.stream() .filter(dish -> dish.getCalories() > 300) .limit(3) .collect(Collectors.toList());
  • 47. Skipping elements 47 • skip(n) method returns another stream that discards the first n elements. • If the stream has fewer elements than n, then an empty stream is returned. • For example, the following code skips the first two dishes that have more than 300 calories and the return the rest. menu.stream() .filter(dish -> dish.getCalories() > 300) .skip(2) .collect(Collectors.toList());
  • 49. Applying function to each elements 49 • map method takes a Function as an argument. This Function is applied to each element, mapping it to new element. • For example, in the following code you pass a method reference Dish::getName to the map method to extract the names of the dishes in the stream. • Because the method getName returns a String, the stream outputted by the map method is of type Stream<String> List<String> dishNames = menu.stream() .map(Dish::getName) .collect(Collectors.toList());
  • 51. Building streams 51 • Streams from values. Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action"); stream.map(String::toUpperCase).forEach(System.out::println); // You can get an empty stream using the empty method as follow: Stream<String> emptyStream = Stream.empty(); • Streams from arrays. int[] numbers = {2, 3, 5, 7, 11, 13}; int sum = Arrays.stream(numbers).sum();
  • 52. Building streams.. 52 • Streams from files. long uniqueWords = 0; // Streams are autoclosable. try (Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())) { uniqueWords = lines // Generate a stream of words .flatMap(line -> Arrays.stream(line.split(" "))) // Remove duplicates .distinct() // Count the number of unique words .count(); } catch (IOException e) { // Deal with the exception if one occurs when opening the file. }
  • 54. Evolving APIs • A Java interface groups related methods together into a contract • Any class which implements this interface must provide an implementation for each method defined by the interface. • This causes a problem when library designers need to update an interface to add a new method. • Java 8 designers faced the exact same issue while introducing Streams API, but somehow they have introduced many new methods to existing APIs. For example, • Collection.streamI() • Collection.parallelStream() • List.sort() 54
  • 55. Evolving APIs... 55 API Version 01 • Consider the following Interface public interface Resizable { int getWidth(); int getHeight(); int setWidth(int width); int setHeight(int height); int setAbsoluteSize(int width, int height); } • Assume you are a library designer and you’ve included the above API in one of your libraries. • Also assume there are external developers who have introduced their own implementations based on this API. • Now what if you want to introduce another method to this interface.
  • 56. Evolving APIs... 56 API Version 02 • Consider the following updated Interface public interface Resizable { int getWidth(); int getHeight(); int setWidth(int width); int setHeight(int height); int setAbsoluteSize(int width, int height); int setRelativeSize(int wFactor, int hFactor); } • This change creates few problems for existing API users.
  • 57. Default methods 57 • A new feature added in Java 8 to help evolve APIs in a compatible way. • An interface can now contain method signatures for which an implementing class doesn’t provide an implementation. • The implementation of a default method should there in the interface itselfdefault void setRelativeSize(int wFactor, int hFactor) { setAbsoluteSize(getWidth() / wFactor, getHeight() / hFactor); } • Default methods are used extensively in the Java 8 API.
  • 58. Abstract classes vs. interfaces in Java 8 58 • What’s the difference between an abstract class and an interface in Java 8? They both can contain abstract methods and methods with a body. 1. A class can extend only from one abstract class, but a class can implement multiple interfaces. 2. An abstract class can enforce a common state through instance variables (fields). An interface cannot have instance variables.
  • 59. 59 Default methods Usage patterns for default methods
  • 60. Optional methods 60 • There are methods in interfaces that we usually don’t implement, we always leave them empty. • When you design an API, now you can provide a default implementation for such methods. • So the concrete classes don’t need to explicitly provide an empty implementation. • This reduces boilerplate code.
  • 61. Resolution rules 61 • What if a class implements two interfaces that have the same default method signature? Which method is the class allowed to use? • Consider the following example.
  • 62. Resolution rules... 62 public interface A { default void hello() { System.out.println("Hello from A"); } } public interface B { default void hello() { System.out.println("Hello from B"); } } public class C implements B, A { public static void main(String[] args) { // Which one gets printed new C().hello(); } }
  • 63. Three resolution rules to know 63 • There are three rules to follow when a class inherits a method with the same signature from multiple places 1. Classes always win. A method declaration in the class or a superclass takes priority over and default method declaration. 2. Otherwise, sub-interfaces win: the method with the same signature in the most specific default-providing interface is selected. 3. Finally, if the choice is still ambiguous, the class inheriting from multiple interfaces has to explicitly select which default method implementation to use by overriding it and calling the desired method explicitly.
  • 64. 64 Parallel data processing Fork/join framework Parallel streams Spliterator
  • 65. Fork/join framework • An implementation of the ExecutorService interface • Designed to recursively split a parallelizable task into smaller tasks, and then combine the results of each subtasks. • ExecutorService distributes those subtasks to worker threads in the ForkJoinPool (thread pool). • These subtasks need to implement RecursiveTasks<R> interface • R is the type of the result produced by the tasks. • RecursiveAction if the task returns no result. • You only need to implement the following abstract method to define a RecursiveTask 65 protected abstract R compute();
  • 67. Fork/join framework - sample 67 /** * Extend {@code RecursiveTask} to create a task usable with the fork/join framework. * Executing a parallel sum using the fork/join framework. */ public class ForkJoinSumCalculator extends RecursiveTask<Long> { // The size of the array under which this task is no longer split into subtasks. public static final long THRESHOLD = 10_000; // The array of numbers to be summed. private final long[] numbers; // The initial and final positions of the portion of the array processed by this subtask. private final int start; private final int end; // Public constructor used to create the main task public ForkJoinSumCalculator(long[] numbers) { this(numbers, 0, numbers.length); } // Private constructor used to recursively create subtasks of the main task. private ForkJoinSumCalculator(long[] numbers, int start, int end) { this.numbers = numbers; this.start = start; this.end = end; }
  • 68. Fork/join framework - sample 68 protected Long compute() { // The size of the portion of the array summed by this task. int length = end - start; if (length <= THRESHOLD) { // If the size if less than or equal to the threshold, compute the result sequentially. return computeSequentially(); } // Create a subtask to sum the first half of the array. ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length / 2); // Asynchronously execute the newly created subtask using the another thread of the ForkJoinPool leftTask.fork(); // Create a subtask to the sum the second half of the array. ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length / 2, end); // Execute this second subtask synchronously, potentially allowing further recursive splits. Long rightResult = rightTask.compute(); // Read the result of the first subtask or wait for it if it isn't ready. Long leftResult = leftTask.join(); // The result of this task is the combination of the two subtasks. return leftResult + rightResult; }
  • 69. Fork/join framework - sample 69 // Simple algorithm calculating the result of a subtask when it's no longer divisible. private long computeSequentially() { long sum = 0; for (int i = start; i < end; i++) { sum += numbers[i]; } return sum; } • Running the ForkJoinSumCalculator. public static long forkJoinSum(long n) { long[] numbers = LongStream.rangeClosed(1, n).toArray(); ForkJoinTask<Long> task = new ForkJoinSumCalculator(numbers); return new ForkJoinPool().invoke(task); }
  • 71. Best practises for using the fork/join framework 71 • Invoke the join method on a task blocks the caller until the result produced by that task is ready. • The invoke method of a ForkJoinPool shouldn’t be used from within a RecursiveTask. • Calling the fork method on a subtask is the way to schedule it on the ForkJoinPool.
  • 72. ForkJoinPool 72 • As a best practise, don’t create ForkJoinPool more than once in your application. • Create is using the default no-argument constructor • This allows the pool to use all the processors available to the JVM. • Calculates the number of threads based on the available processors.
  • 73. 73 • Allows you to execute operations in parallel on a collection of data without much effort. • Allows you to declaratively turn a sequential stream into a parallel one. • Uses the fork/join framework under the hood. • A parallel stream is a stream that splits its elements into multiple chunks, processing each chunks with a different thread. • This should keep all your cores busy by equally partitioning chunks • Suppose you need to write a method accepting a number n as an argument and returning the sum of all the numbers from 1 to the given amount. Let’s optimize this method step by step. Parallel streams
  • 74. 74 • Using traditional java style. Parallel streams... public static long iterativeSum(long n) { long result = 0; for (long i = 0; i <= n; i++) { result += i; } return result; } //Result Iterative sum done in: 3 msecs
  • 75. 75 • Using infinite stream of numbers, limiting it to the passed number, and then reduce the resulting stream with a BinaryOperator thats just sums two numbers Parallel streams... public static long rangedSum(long n) { return LongStream.rangeClosed(1, n) .reduce(0L, Long::sum); } //Result Sequential sum done in: 4 msecs • Previous one runs faster because its works at a much lower level and, more important, doesn’t need to perform any boxing or unboxing for primitive values
  • 77. 77 • Turning the sequential stream into a parallel one. Parallel streams... public static long parallelRangedSum(long n) { return LongStream.rangeClosed(1, n) .parallel() .reduce(0L, Long::sum); } //Result Sequential sum done in: 1 msecs • Here the difference is that the stream is internally divided into multiple chunks. Reduction operation can work on the various chunks independently and in parallel.
  • 79. 79 • How can we configure the thread pool size here? • Parallel streams internally use the default ForkJoinPool • This pool has as many threads as you have processors, as returned by Runtime.getRuntime().availableProcessors(). • You can change the size of the ForkJoinPool using the following system property. Configuring the thread pool System.setProperty(“java.util.concurrent.ForkJoinPool.common.parallelism”, 12) • This is a global setting, so it will affect all the parallel streams in your code. • The default value of this pool is equal to the number of processors on your machine and it is a meaningful default. • Don’t change it unless you have a very good reason for doing so.
  • 80. 80 • If in doubt, measure. Turning a sequential stream into a parallel one is trivial but not always the right thing to do. • Watch out for boxing. Automatic boxing and unboxing operations can dramatically hurt performance. • Some operations naturally perform worse on a parallel stream than on a sequential stream. For example limit and findFirst vs. findAny • Consider the total computational cost of the pipeline of operations performed by the stream. With N being the number of elements to be processed and Q the approximate cost of processing one of these elements through the stream pipeline, the product of N*Q gives a rough qualitative estimation of this cost. A higher value for Q implies a better chance of good performance when using a parallel stream. Using parallel streams effectively
  • 81. 81 • Code readability can be very subjective. • Improve code readability means ensuring your code is understandable and maintainable by people beside you. • How Java 8 allows you to improve code readability? • You can reduce the verbosity of your code, making it easier to understand. • You can improve the intent of your code by using method references and the Streams API • Following are three simple refactorings that use lambdas, method references , and streams • Refactoring anonymous classes to lambda expressions • Refactoring lambda expressions to method references • Refactoring imperative-style data processing to streams. Improving code readability
  • 82. 82 • Try to convert anonymous classes implementing one single abstract method to lambda expressions. • But sometime, you may get into issues • The meanings of this and super are different from anonymous classes and lambda expressions. • Inside an anonymous class, this refers to the anonymous class itself, but inside a lambda it refers to the enclosing class. • Anonymous classes are allowed to shadow variables from the enclosing class. Lambda expressions can’t do that. From anonymous classes to lambdas
  • 83. 83 From anonymous classes to lambdas...
  • 84. 84 • Converting an anonymous class to a lambda expression can make the resulting code ambiguous in the context of overloading. • The type of the anonymous class is explicit at instantiation. • But, the type of the lambda depends on its context. From anonymous classes to lambdas... • You can now pass an anonymous class implementing Task without a problem.
  • 85. 85 • But converting the previous anonymous class to a lambda results in an ambiguous method call, because both Runnable and Task are valid target types. From anonymous classes to lambdas... • You can solve the ambiguity by the providing an explicit cast.
  • 86. 86 Best practises List <String> myList = …; if (myList.size > 0) { … } if myList.isEmpty() { … }
  • 87. 87 Best practises Returning Empty Collections instead of Null public static List<Pet> getAllPets(){ List<Pet> lPets = new ArrayList()<Pet>(); ................ return lPets; }
  • 88. 88 Best practises Avoid unnecessary Objects public static List<Pet> getAllPets(){ List<Pet> lPets = null; //if throw exception etc ................ if (lPets == null) { lPets = new ArrayList()<Pet>(); } ................ return lPets; } //Slower Instantiation String bad = new String("Yet another string object"); //Faster Instantiation String good = "Yet another string object";
  • 89. 89 Best practises Dilemma between Array and ArrayList • Arrays have fixed size but ArrayLists have variable sizes. Since the size of Array is fixed, the memory gets allocated at the time of declaration of Array type variable. Hence, Arrays are very fast. On the other hand, if we are not aware of the size of the data, then ArrayList is More data will lead to ArrayOutOfBoundException and less data will cause wastage of storage space. • It is much easier to Add or Remove elements from ArrayList than Array • Array can be multi-dimensional but ArrayList can be only one dimension.
  • 90. 90 Best practises Difference between single quotes and double quotes public static void main (String [] args) { System.out.println("H" + "I"); System.out.println('H' + 'I'); }
  • 91. 91 Best practises Choice between Float and Double 45.123456…? Most processors take nearly the same amount of processing time to perform operations on Float and Double. Double offers far more precision in the same amount of computation time.