Java 8 came out early last year and Java 7 is now, at the end of life, making Java 8 the only Oracle supported option. However, since developers value stability over trendiness, many of us are still working with Java 7, or even 6. Let’s look at some features of Java 8, and provide some arguments to persuade your code to upgrade with best practices.
This presentaion provides and overview of the new features of Java 8, namely default methods, functional interfaces, lambdas, method references, streams and Optional vs NullPointerException.
This presentation by Arkadii Tetelman (Lead Software Engineer, GlobalLogic) was delivered at Java.io 3.0 conference in Kharkiv on March 22, 2016.
This presentaion provides and overview of the new features of Java 8, namely default methods, functional interfaces, lambdas, method references, streams and Optional vs NullPointerException.
This presentation by Arkadii Tetelman (Lead Software Engineer, GlobalLogic) was delivered at Java.io 3.0 conference in Kharkiv on March 22, 2016.
In this session you will learn:
List – ArrayList, LinkedList
Set – HashSet, LinkedHashSet, TreeSet
For more information: https://www.mindsmapped.com/courses/software-development/become-a-java-developer-hands-on-training/
Functional Thinking - Programming with Lambdas in Java 8Ganesh Samarthyam
Functional programming is on the rise. Almost all major and mainstream languages support functional programming features, including C++, Java, Swift, and Python, and Visual Basic. With Java 8’s lambda functions, Java now supports functional programming. Moving to functional programming can result in significantly better code and productivity gains. However, it requires a paradigm shift: you need to move away from imperative and object-oriented thinking to start thinking functionally. That’s what this workshop will help you achieve: it will help you make your shift towards functional programming. The workshop will introduce lambda functions in Java with examples from Java library itself. Presented in OSI Days 2015 workshop - http://osidays.com/osidays/shifting-to-functional-programming-lambdas-for-java-developers/
This presentation introduces some concepts about the Java Collection framework. These slides introduce the following concepts:
- Collections and iterators
- Linked list and array list
- Hash set and tree set
- Maps
- The collection framework
The presentation is took from the Java course I run in the bachelor-level informatics curriculum at the University of Padova.
To learn important concept of Collection and its handling plus its advantages and different class & child class of Collection and their implementations. Important interview questions of the collection.
Beyond xUnit example-based testing: property-based testing with ScalaCheckFranklin Chen
Test-Driven Development has become deservedly popular in the past decade, with easy-to-use xUnit unit testing frameworks leading the way toward encouraging developers to write tests. But xUnit has limitations: how does one know one has written enough test cases for a desired behavior? And what if the behavior is conditional on other behavior? Property-based testing, first popularized for Haskell with the QuickCheck library, but available now for other languages as well, offers a powerful addition to one's testing toolkit.
I will discuss the concepts of property-based testing and illustrate them concretely using ScalaCheck for Scala, and point toward similar test frameworks in other languages.
Java 8 Stream API. A different way to process collections.David Gómez García
A look on one of the features of Java 8 hidden behind the lambdas. A different way to iterate Collections. You'll never see the Collecions the same way.
These are the slides I used on my talk at the "Tech Thursday" by Oracle in June in Madrid.
In this session you will learn:
List – ArrayList, LinkedList
Set – HashSet, LinkedHashSet, TreeSet
For more information: https://www.mindsmapped.com/courses/software-development/become-a-java-developer-hands-on-training/
Functional Thinking - Programming with Lambdas in Java 8Ganesh Samarthyam
Functional programming is on the rise. Almost all major and mainstream languages support functional programming features, including C++, Java, Swift, and Python, and Visual Basic. With Java 8’s lambda functions, Java now supports functional programming. Moving to functional programming can result in significantly better code and productivity gains. However, it requires a paradigm shift: you need to move away from imperative and object-oriented thinking to start thinking functionally. That’s what this workshop will help you achieve: it will help you make your shift towards functional programming. The workshop will introduce lambda functions in Java with examples from Java library itself. Presented in OSI Days 2015 workshop - http://osidays.com/osidays/shifting-to-functional-programming-lambdas-for-java-developers/
This presentation introduces some concepts about the Java Collection framework. These slides introduce the following concepts:
- Collections and iterators
- Linked list and array list
- Hash set and tree set
- Maps
- The collection framework
The presentation is took from the Java course I run in the bachelor-level informatics curriculum at the University of Padova.
To learn important concept of Collection and its handling plus its advantages and different class & child class of Collection and their implementations. Important interview questions of the collection.
Beyond xUnit example-based testing: property-based testing with ScalaCheckFranklin Chen
Test-Driven Development has become deservedly popular in the past decade, with easy-to-use xUnit unit testing frameworks leading the way toward encouraging developers to write tests. But xUnit has limitations: how does one know one has written enough test cases for a desired behavior? And what if the behavior is conditional on other behavior? Property-based testing, first popularized for Haskell with the QuickCheck library, but available now for other languages as well, offers a powerful addition to one's testing toolkit.
I will discuss the concepts of property-based testing and illustrate them concretely using ScalaCheck for Scala, and point toward similar test frameworks in other languages.
Java 8 Stream API. A different way to process collections.David Gómez García
A look on one of the features of Java 8 hidden behind the lambdas. A different way to iterate Collections. You'll never see the Collecions the same way.
These are the slides I used on my talk at the "Tech Thursday" by Oracle in June in Madrid.
Lo que hay que saber sobre las veeduriasGerman Erazo
Es un documento realizado por la personería municipal del municipio de Calima - Darien en el departamento del Valle. Es un texto interesante que enseña las pautas para ejercer este derecho ciudadano contemplado en la Constitución Política de la República de Colombia
The slides of my JavaOne 2016 talk. This talk is a tutorial on how to write lambda expressions, how to compose them using default methods in functional interfaces, and how to create factory methods in those interfaces. Many examples and patterns are provided.
Lazy Java by Mario Fusco
Like all imperative languages Java is, with some minor but notable exceptions, an eagerly evaluated programming language. Nevertheless the introduction of lambdas in Java 8 also allowed the adoption of some lazy patterns and data structures that are more typically employed in functional languages. Streams represent the most evident example of how also native Java API has taken advantage of laziness, but there is a number of other interesting scenarios where laziness can be an effective solution to quite common problems. In fact laziness is the only possible technique to process potentially infinite amount of data, or more in general to delay the expensive evaluation of an expression only when and if it is necessary. But laziness is even more than that: for instance the reader monad delays not only a computation but also the need of external dependencies thus lowering the abuse of dependency injection, while a trampoline uses laziness to delay and then linearize recursive calls preventing the overflow of the stack. The purpose of this talk is illustrating why and how implementing laziness in Java with practical examples delivered with both slides and live coding sessions.
Mario Fusco - Lazy Java - Codemotion Milan 2018Codemotion
Like all imperative languages Java is eagerly evaluated, but the introduction of lambdas allowed the adoption of some lazy patterns and data structures that are typically functional. Streams are the most evident example of a native Java API using laziness, but there are other cases where laziness is an effective solution to common problems. In fact it makes possible to process infinite amount of data, but it is even more than that. This talk shows why and how implementing laziness in Java with practical examples delivered with both slides and live coding sessions.
Java is Object Oriented Programming. Java 8 is the latest version of the Java which is used by many companies for the development in many areas. Mobile, Web, Standalone applications.
The slides of my JavaOne 2017 talk. It describes how you can create API using functional interfaces, default and static methods starting with Java 8. You can watch the video here: https://www.youtube.com/watch?v=64UO1YjVcZ0
Presentation on the new features introduced in JDK 8, presented on the 26.02.2013 in Sofia University in front of students and members of the Bulgarian java user group.
Assg 07 Templates and Operator OverloadingCOSC 2336 Sprin.docxfestockton
Assg 07: Templates and Operator Overloading
COSC 2336 Spring 2019
Dates:
Due: Thursday March 07, by Midnight (note the di�erent due date)
Objectives
� Practice creating a more realistic abstract data type ADT
� Using operator overloading to do output, insertion and access into a
list.
� Use templates so our ADT can hold objects of any type
Description
In this assignment you will be practicing operator overloading. I will also,
for extra credit, give an additional task to convert your class into a class
template, so that it will work as a container for any type.
In this assignment you will be expanding on / creating a new version of
the ListType data type we have seen examples of before in class. Your task is
to create a ListType that holds a list of integers. You will be asked to create
several member functions, and then to create several overloaded operators
for your list of integers. Your basic task is to user operator overloading to
support appending and prepending to a list, outputting the list as a string
and to an output stream, accessing the list (using the indexing operator[]),
and concatenating lists together (using operator+).
I have given you a starting template for your ListType that already
contains 3 versions of the class constructor. I have also already provided you
the operator= implementation, to provide the copy operator for your class.
You should �rst get your class to work as a simple ListType that holds a
list of integers. If you get your class working for integers and submit it, you
1
can then turn your class into a template class, so that your list can work on
objects of any type. I will give up to 10 bonus points for implementations of
working class templates, if you �rst mostly have your basic ListType working
for simple integers. As usual I have also given a �le with a main function
and a lot of commented out tests. You should implement the class member
functions in the order speci�ed next, commenting out each test one at a time,
to incrementally develop and test your ListType class implementation.
For this assignment you need to perform the following tasks.
1. As mentioned in the starting template I have given you a starting class
de�nition, some class constructors and the destructor, and the copy
operator=. You �rst need to write two simple getter methods in order
to access the size and allocSize class member values. These should be
called getSize() and getAllocSize() respectively. These functions
should be class const functions (you guarantee that calling them will
not cause the class to be modi�ed. These functions take no parameters
as input. They both return an int value, because the size and allocSize
member parameters are both integer values.
2. Write a function called tostring(). This function will be a const class
function (the class is not modi�ed when it is called). This function
takes no parameters as input, and it returns a string. We use this
function in our testing, so you need to get ...
Since its first public release over two decades ago, the Java platform has become ubiquitous in virtually all areas of computing; from embedded systems to enterprise applications. As the demands of modern software development have evolved, so too have programming languages. There are many languages on the Java platform designed to be a “better Java”; though none are as widespread as Java itself. Despite the somewhat conservative nature of Java as a language, there have been a number of notable additions designed to address the challenges developers face without breaking compatibility. This presentation aims to provide an overview of the newer language features and APIs in recent releases of Java in the hope of increasing developer productivity.
Epistemic Interaction - tuning interfaces to provide information for AI supportAlan Dix
Paper presented at SYNERGY workshop at AVI 2024, Genoa, Italy. 3rd June 2024
https://alandix.com/academic/papers/synergy2024-epistemic/
As machine learning integrates deeper into human-computer interactions, the concept of epistemic interaction emerges, aiming to refine these interactions to enhance system adaptability. This approach encourages minor, intentional adjustments in user behaviour to enrich the data available for system learning. This paper introduces epistemic interaction within the context of human-system communication, illustrating how deliberate interaction design can improve system understanding and adaptation. Through concrete examples, we demonstrate the potential of epistemic interaction to significantly advance human-computer interaction by leveraging intuitive human communication strategies to inform system design and functionality, offering a novel pathway for enriching user-system engagements.
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Albert Hoitingh
In this session I delve into the encryption technology used in Microsoft 365 and Microsoft Purview. Including the concepts of Customer Key and Double Key Encryption.
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Ramesh Iyer
In today's fast-changing business world, Companies that adapt and embrace new ideas often need help to keep up with the competition. However, fostering a culture of innovation takes much work. It takes vision, leadership and willingness to take risks in the right proportion. Sachin Dev Duggal, co-founder of Builder.ai, has perfected the art of this balance, creating a company culture where creativity and growth are nurtured at each stage.
UiPath Test Automation using UiPath Test Suite series, part 3DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 3. In this session, we will cover desktop automation along with UI automation.
Topics covered:
UI automation Introduction,
UI automation Sample
Desktop automation flow
Pradeep Chinnala, Senior Consultant Automation Developer @WonderBotz and UiPath MVP
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
UiPath Test Automation using UiPath Test Suite series, part 4DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 4. In this session, we will cover Test Manager overview along with SAP heatmap.
The UiPath Test Manager overview with SAP heatmap webinar offers a concise yet comprehensive exploration of the role of a Test Manager within SAP environments, coupled with the utilization of heatmaps for effective testing strategies.
Participants will gain insights into the responsibilities, challenges, and best practices associated with test management in SAP projects. Additionally, the webinar delves into the significance of heatmaps as a visual aid for identifying testing priorities, areas of risk, and resource allocation within SAP landscapes. Through this session, attendees can expect to enhance their understanding of test management principles while learning practical approaches to optimize testing processes in SAP environments using heatmap visualization techniques
What will you get from this session?
1. Insights into SAP testing best practices
2. Heatmap utilization for testing
3. Optimization of testing processes
4. Demo
Topics covered:
Execution from the test manager
Orchestrator execution result
Defect reporting
SAP heatmap example with demo
Speaker:
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
The publishing industry has been selling digital audiobooks and ebooks for over a decade and has found its groove. What’s changed? What has stayed the same? Where do we go from here? Join a group of leading sales peers from across the industry for a conversation about the lessons learned since the popularization of digital books, best practices, digital book supply chain management, and more.
Link to video recording: https://bnctechforum.ca/sessions/selling-digital-books-in-2024-insights-from-industry-leaders/
Presented by BookNet Canada on May 28, 2024, with support from the Department of Canadian Heritage.
The Art of the Pitch: WordPress Relationships and SalesLaura Byrne
Clients don’t know what they don’t know. What web solutions are right for them? How does WordPress come into the picture? How do you make sure you understand scope and timeline? What do you do if sometime changes?
All these questions and more will be explored as we talk about matching clients’ needs with what your agency offers without pulling teeth or pulling your hair out. Practical tips, and strategies for successful relationship building that leads to closing the deal.
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualityInflectra
In this insightful webinar, Inflectra explores how artificial intelligence (AI) is transforming software development and testing. Discover how AI-powered tools are revolutionizing every stage of the software development lifecycle (SDLC), from design and prototyping to testing, deployment, and monitoring.
Learn about:
• The Future of Testing: How AI is shifting testing towards verification, analysis, and higher-level skills, while reducing repetitive tasks.
• Test Automation: How AI-powered test case generation, optimization, and self-healing tests are making testing more efficient and effective.
• Visual Testing: Explore the emerging capabilities of AI in visual testing and how it's set to revolutionize UI verification.
• Inflectra's AI Solutions: See demonstrations of Inflectra's cutting-edge AI tools like the ChatGPT plugin and Azure Open AI platform, designed to streamline your testing process.
Whether you're a developer, tester, or QA professional, this webinar will give you valuable insights into how AI is shaping the future of software delivery.
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
Sidekick Solutions uses Bonterra Impact Management (fka Social Solutions Apricot) and automation solutions to integrate data for business workflows.
We believe integration and automation are essential to user experience and the promise of efficient work through technology. Automation is the critical ingredient to realizing that full vision. We develop integration products and services for Bonterra Case Management software to support the deployment of automations for a variety of use cases.
This video focuses on the notifications, alerts, and approval requests using Slack for Bonterra Impact Management. The solutions covered in this webinar can also be deployed for Microsoft Teams.
Interested in deploying notification automations for Bonterra Impact Management? Contact us at sales@sidekicksolutionsllc.com to discuss next steps.
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.
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?
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.
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.
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
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.
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.