30
FUNctional Programming in Java 8 An introduction to functional programming, lambdas, and streams Richard Walker September 2016

FUNctional Programming in Java 8

Embed Size (px)

Citation preview

Page 1: FUNctional Programming in Java 8

FUNctional Programming in Java

8An introduction to functional programming, lambdas, and

streams

Richard WalkerSeptember 2016

Page 2: FUNctional Programming in Java 8

Outline Java is changing

Paradigm shift

What is functional programming?

Anonymous functions (Lambdas)

Streams

Filter

Map

Reduce

Examples

Page 3: FUNctional Programming in Java 8

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

Page 4: FUNctional Programming in Java 8

We’re still learning how to code

Procedur

al

Object-

Oriented

Functional

C, Fortran, Perl

Java, C++, Python

Lisp, Scala, Clojure, Java 8*

Page 6: FUNctional Programming in Java 8

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

Page 7: FUNctional Programming in Java 8

Quick Quiz

Imperative Wayint result = 0;

for(int e: numbers) {

if(e % 2 == 0) {

result += e * 2;

}

}

Functional Way Inumbers.stream()

.filter(e -> e % 2 == 0)

.mapToInt(e -> e * 2)

.sum();

Functional Way IInumbers.stream()

.filter(Numbers::evenNumber)

.mapToInt(Numbers::doubleNumber)

.sum();

Page 8: FUNctional Programming in Java 8

Lambdas Anonymous functions

like an anonymous inner class Functional Interfaces

An interface with one abstract method (NEW!)* 1st-class citizens in Java 8Format:(parameters) -> (expression)

Examples:(int a, int b) -> a * b(a, b) -> a * b

Page 9: FUNctional Programming in Java 8

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

Page 10: FUNctional Programming in Java 8

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);

}

});

Page 11: FUNctional Programming in Java 8

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);

}

});

Page 12: FUNctional Programming in Java 8

Lambda Example// Java 8

List<Person> people = loadPeople();

Collections.sort(people,

(Person p1, Person p2)

p1.name.compareTo(p2.name);

);

Page 13: FUNctional Programming in Java 8

Lambda Example// Java 8

List<Person> people = loadPeople();

Collections.sort(people,

(Person p1, Person p2) -> p1.name.compareTo(p2.name);

);

Page 14: FUNctional Programming in Java 8

Lambda Example// Java 8

List<Person> people = loadPeople();

Collections.sort(people,

(Person p1, Person p2) -> p1.name.compareTo(p2.name);

);

Page 15: FUNctional Programming in Java 8

Lambda Example// Java 8

List<Person> people = loadPeople();

Collections.sort(people,

(p1, p2) -> p1.name.compareTo(p2.name);

);

Page 16: FUNctional Programming in Java 8

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.

Page 17: FUNctional Programming in Java 8

Streams“The gateway drug of Java 8” - Venkat Subramaniam

Page 18: FUNctional Programming in Java 8

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

Page 19: FUNctional Programming in Java 8

Filtering (Extracts)

// Filtering unique elements

List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);

numbers.stream()

.filter(i -> i % 2 == 0)

.distinct()

.forEach(System.out::println);

Page 20: FUNctional Programming in Java 8

Mapping (Transforms)

// Map

List<String> words = Arrays.asList("Hello", "World");

List<Integer> wordLengths = words.stream()

.map(String::length)

.collect(toList());

System.out.println(wordLengths);

Page 21: FUNctional Programming in Java 8

Reducing (Folds/Massages)

List<Integer> numbers = Arrays.asList(3,4,5,1,2);

int sum = numbers.stream()

.reduce(0, (a, b) -> a + b);

System.out.println(sum);

int sum2 = numbers.stream()

.reduce(0, Integer::sum);

System.out.println(sum2);

Page 22: FUNctional Programming in Java 8

Filtering (Extracts) faster!

// Filtering unique elements

List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);

numbers.parallelStream() .filter(i -> i % 2 == 0)

.distinct()

.forEach(System.out::println);

Page 23: FUNctional Programming in Java 8

ExamplesHow can I actually use this at work?

Page 24: FUNctional Programming in Java 8

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

Page 25: FUNctional Programming in Java 8

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()));

Page 26: FUNctional Programming in Java 8

Real-life examplesReducing QA work one line at a time

Page 27: FUNctional Programming in Java 8

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

Page 28: FUNctional Programming in Java 8

QA Implementation Pt.2public 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

Page 29: FUNctional Programming in Java 8

Differences

Imperative 9 Lines 286 Chars

Declarative 7 Lines 194 Chars

92 characters less32.17% decrease!

Page 30: FUNctional Programming in Java 8

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*