This document provides an introduction to functional programming concepts in Java 8 including lambdas, streams, and examples of how to apply functional programming techniques. It outlines key functional programming concepts like declarative programming and composing small functions without side effects. It also covers Java 8 features like lambda expressions, functional interfaces, and the Stream API for filtering, mapping, and reducing collections in a declarative way. Examples are provided for sorting a list, finding word lengths, summing numbers, and filtering/mapping over collections in a functional style.
1. FUNctional Programming
in Java 8
An introduction to functional programming, lambdas, and streams
Richard Walker
September 2016
2. Outline
Java is changing
Paradigm shift
What is functional programming?
Anonymous functions (Lambdas)
Streams
Filter
Map
Reduce
Examples
3. Java is evolving and so should we
“It is not the strongest of the species that survives, nor the most intelligent
that survives. It is the one that is most adaptable to change” – Charles Darwin
Java 8 allows for cleaner and more concise code
Takes advantage of multicore architectures without synchronized
Collections.sort(inventory, new Comparator <Apple>() {
public int compare (Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
});
inventory.sort(comparing(Apple::getWeight)); Java 8
4. We’re still learning how to code
Procedural
Object-
Oriented
Functional
C, Fortran,
Perl
Java, C++,
Python
Lisp, Scala, Clojure,
Java 8*
6. What is functional programming?
Declarative Programming Paradigm
What you want done instead of how it gets done
Accomplish tasks by composing small functions
No side effects
No mutation = easier debugging
Allows for safe parallelization
7. Quick Quiz
Imperative Way
int result = 0;
for(int e: numbers) {
if(e % 2 == 0) {
result += e * 2;
}
}
Functional Way I
numbers.stream()
.filter(e -> e % 2 == 0)
.mapToInt(e -> e * 2)
.sum();
Functional Way II
numbers.stream()
.filter(Numbers::evenNumber)
.mapToInt(Numbers::doubleNumber)
.sum();
8. Lambdas
Anonymous functions
like an anonymous inner class
Functional Interfaces
An interface with one abstract method (NEW!)*
1st-class citizens in Java 8
Format:
(parameters) -> (expression)
Examples:
(int a, int b) -> a * b
(a, b) -> a * b
9. Functional Interfaces in Java
Oracle provided a bunch of them fresh out of the box!
Predicate<T> : T -> Boolean
Function<T, R> : T -> R
https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
10. Lambda Example
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>()
{
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
11. Lambda Example
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>()
{
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
12. Lambda Example
// Java 8
List<Person> people = loadPeople();
Collections.sort(people,
(Person p1, Person p2)
p1.name.compareTo(p2.name);
);
13. Lambda Example
// Java 8
List<Person> people = loadPeople();
Collections.sort(people,
(Person p1, Person p2) -> p1.name.compareTo(p2.name);
);
14. Lambda Example
// Java 8
List<Person> people = loadPeople();
Collections.sort(people,
(Person p1, Person p2) -> p1.name.compareTo(p2.name);
);
15. Lambda Example
// Java 8
List<Person> people = loadPeople();
Collections.sort(people,
(p1, p2) -> p1.name.compareTo(p2.name);
);
16. Lambda Example
// Java 8
List<Person> people = loadPeople();
people.sort((p1, p2) -> p1.name.compareTo(p2.name));
• Less code
• Easier to read
• Less chance for screw ups
We’re using the new sort API added to java.util.List in Java 8 – instead of the old Collections.sort API.
18. What are Streams?
Allows for Collection manipulation in a
Declarative way
Functional
Allows us to abstract away from iteration
Less boilerplate code
Allows for composable code
Greater Flexibility
Allows for easy (free) parallelization
Better Performance
24. class Person {
Gender gender; String name;
public Gender getGender() { return gender; }
public String getName() { return name; }
}
enum Gender { MALE, FEMALE, OTHER }
List<String> names = new ArrayList<String>();
List<Person> people = …
people.stream()
.filter(p -> p.getGender() == Gender.FEMALE)
.map(Person::getName)
.map(String::toUpperCase)
.forEach(name -> names.add(name));
List of uppercase names of all the “FEMALE” people in
that list
25. Get the unique surnames in uppercase of the first
15 book authors that are 50 years old or older.
library.stream()
.map(book -> book.getAuthor())
.filter(author -> author.getAge() >= 50)
.map(Author::getSurname)
.map(String::toUpperCase)
.distinct()
.limit(15)
.collect(toList()));
27. QA Implementation Pt.1
public static PartnerInfo[] arrayCopy(final PartnerInfo... info) {
if (info == null) {
return null;
}
final PartnerInfo[] result = new PartnerInfo[info.length];
for (int i = 0; i < info.length; i++) {
result[i] = new PartnerInfo(info[i]);
}
return result;
}
286 chars, 9 lines
28. QA Implementation Pt.2
public static PartnerInfo[] arrayCopy(final PartnerInfo... info) {
if (info == null) {
return null;
}
// Create a new copy for each PartnerInfo in the list
return Arrays.stream(info)
.map(PartnerInfo::new)
.toArray(PartnerInfo[]::new);
}
194 chars, 7 lines
30. Conclusion
Paradigms are changing, and languages are evolving
Java 8 has a host of new features:
Lambdas
Stream API
Functional Code has the following benefits:
Flexible
Less Code*
Notas del editor
Since the release of JDK 1.0 in 1996 Java has won a large following of supporters in the programming community, and it has evolved till it’s Java 8 release in 2014.