SlideShare ist ein Scribd-Unternehmen logo
1 von 92
Downloaden Sie, um offline zu lesen
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 !

Weitere ähnliche Inhalte

Was ist angesagt?

Collections - Lists & sets
Collections - Lists & setsCollections - Lists & sets
Collections - Lists & setsRatnaJava
 
Functional Thinking - Programming with Lambdas in Java 8
Functional Thinking - Programming with Lambdas in Java 8Functional Thinking - Programming with Lambdas in Java 8
Functional Thinking - Programming with Lambdas in Java 8Ganesh Samarthyam
 
Java Generics for Dummies
Java Generics for DummiesJava Generics for Dummies
Java Generics for Dummiesknutmork
 
Functional Objects & Function and Closures
Functional Objects  & Function and ClosuresFunctional Objects  & Function and Closures
Functional Objects & Function and ClosuresSandip Kumar
 
Java - Collections framework
Java - Collections frameworkJava - Collections framework
Java - Collections frameworkRiccardo Cardin
 
Java Presentation
Java PresentationJava Presentation
Java Presentationmdfkhan625
 
Beyond xUnit example-based testing: property-based testing with ScalaCheck
Beyond xUnit example-based testing: property-based testing with ScalaCheckBeyond xUnit example-based testing: property-based testing with ScalaCheck
Beyond xUnit example-based testing: property-based testing with ScalaCheckFranklin Chen
 
java collections
java collectionsjava collections
java collectionsjaveed_mhd
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.David Gómez García
 

Was ist angesagt? (17)

Collections - Lists & sets
Collections - Lists & setsCollections - Lists & sets
Collections - Lists & sets
 
Generics
GenericsGenerics
Generics
 
Collections framework
Collections frameworkCollections framework
Collections framework
 
Functional Thinking - Programming with Lambdas in Java 8
Functional Thinking - Programming with Lambdas in Java 8Functional Thinking - Programming with Lambdas in Java 8
Functional Thinking - Programming with Lambdas in Java 8
 
Java Generics for Dummies
Java Generics for DummiesJava Generics for Dummies
Java Generics for Dummies
 
Java 8: the good parts!
Java 8: the good parts!Java 8: the good parts!
Java 8: the good parts!
 
Functional Objects & Function and Closures
Functional Objects  & Function and ClosuresFunctional Objects  & Function and Closures
Functional Objects & Function and Closures
 
Java8lambda
Java8lambda Java8lambda
Java8lambda
 
Java - Collections framework
Java - Collections frameworkJava - Collections framework
Java - Collections framework
 
Java8 features
Java8 featuresJava8 features
Java8 features
 
Collections in Java Notes
Collections in Java NotesCollections in Java Notes
Collections in Java Notes
 
Java Presentation
Java PresentationJava Presentation
Java Presentation
 
Scala oo (1)
Scala oo (1)Scala oo (1)
Scala oo (1)
 
Java collections notes
Java collections notesJava collections notes
Java collections notes
 
Beyond xUnit example-based testing: property-based testing with ScalaCheck
Beyond xUnit example-based testing: property-based testing with ScalaCheckBeyond xUnit example-based testing: property-based testing with ScalaCheck
Beyond xUnit example-based testing: property-based testing with ScalaCheck
 
java collections
java collectionsjava collections
java collections
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
 

Ähnlich wie 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
 
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
 
03-inheritance.ppt
03-inheritance.ppt03-inheritance.ppt
03-inheritance.pptSaiM947604
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentationVan Huong
 
What's new in java 8
What's new in java 8What's new in java 8
What's new in java 8Dian Aditya
 

Ähnlich wie Java 8 ​and ​Best Practices (20)

Java8
Java8Java8
Java8
 
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
 
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
 
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
 
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
 
03-inheritance.ppt
03-inheritance.ppt03-inheritance.ppt
03-inheritance.ppt
 
Lambdas and Laughs
Lambdas and LaughsLambdas and Laughs
Lambdas and Laughs
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
 
What's new in java 8
What's new in java 8What's new in java 8
What's new in java 8
 

Kürzlich hochgeladen

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 

Kürzlich hochgeladen (20)

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 

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.