Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… ·...

32
Java 8 Functional Interfaces Function Douglas C. Schmidt

Transcript of Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… ·...

Page 1: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

Java 8 Functional Interfaces

Function

Douglas C. Schmidt

Page 2: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

Learning Objectives in This Lesson• Recognize foundational functional programming features in Java 8, e.g.,

• Lambda expressions

• Method & constructor references

• Key functional interfaces

• Predicate

• Function

Page 3: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

Overview ofFunctional Interfaces: Function

Douglas C. Schmidt

Page 4: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

See docs.oracle.com/javase/8/docs/api/java/util/function/Function.html

Page 5: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

See docs.oracle.com/javase/8/docs/api/java/util/function/Function.html

Function is a generic interface that is parameterized by two reference types.

Page 6: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

See docs.oracle.com/javase/8/docs/api/java/util/function/Function.html

Its abstract method is passed a parameter of type T & returns a value of type R.

Page 7: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

See github.com/douglascraigschmidt/LiveLessons/tree/master/Java8/ex9

Overview of Common Functional Interfaces: Function

Map<Integer, Integer> primeCache =

new ConcurrentHashMap<>();

...

Long smallestFactor = primeCache.computeIfAbsent

(primeCandidate, (key) -> primeChecker(key));

...

Integer primeChecker(Integer primeCandidate) {

... // Returns 0 if a number is prime or the smallest

// factor if it’s not prime

}

This map caches the results of prime number computations.

Page 8: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

Map<Integer, Integer> primeCache =

new ConcurrentHashMap<>();

...

Long smallestFactor = primeCache.computeIfAbsent

(primeCandidate, (key) -> primeChecker(key));

...

Integer primeChecker(Integer primeCandidate) {

... // Returns 0 if a number is prime or the smallest

// factor if it’s not prime

}

If key isn’t already associated with a value, compute the value using the given mapping

function & enter it into the map.

See docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#computeIfAbsent

Page 9: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

Map<Integer, Integer> primeCache =

new ConcurrentHashMap<>();

...

Long smallestFactor = primeCache.computeIfAbsent

(primeCandidate, (key) -> primeChecker(key));

...

Integer primeChecker(Integer primeCandidate) {

... // Returns 0 if a number is prime or the smallest

// factor if it’s not prime

}

This method provides atomic “check then act” semantics.

See dig.cs.illinois.edu/papers/checkThenAct.pdf

Page 10: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

Map<Integer, Integer> primeCache =

new ConcurrentHashMap<>();

...

Long smallestFactor = primeCache.computeIfAbsent

(primeCandidate, (key) -> primeChecker(key));

...

Integer primeChecker(Integer primeCandidate) {

... // Returns 0 if a number is prime or the smallest

// factor if it’s not prime

}

A lambda expression that calls a function.

Page 11: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

Map<Integer, Integer> primeCache =

new ConcurrentHashMap<>();

...

Long smallestFactor = primeCache.computeIfAbsent

(primeCandidate, this::primeChecker);

...

Integer primeChecker(Integer primeCandidate) {

... // Returns 0 if a number is prime or the smallest

// factor if it’s not prime

}

Could also be passed as a method reference.

Page 12: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

class ConcurrentHashMap<K,V> ...

public V computeIfAbsent(K key,

Function<? super K, ? extends V> mappingFunction) {

...

if ((f = tabAt(tab, i = (n - 1) & h)) == null)

...

if ((val = mappingFunction.apply(key)) != null)

node = new Node<K,V>(h, key, val, null);

...

Here’s how computeIfAbsent() uses the function passed to it (atomically).

Page 13: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

class ConcurrentHashMap<K,V> ...

public V computeIfAbsent(K key,

Function<? super K, ? extends V> mappingFunction) {

...

if ((f = tabAt(tab, i = (n - 1) & h)) == null)

...

if ((val = mappingFunction.apply(key)) != null)

node = new Node<K,V>(h, key, val, null);

...

See docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html

‘super’ is a lower-bounded wildcard that restricts the unknown type to be a specific type or a super type of that type.

Page 14: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

class ConcurrentHashMap<K,V> ...

public V computeIfAbsent(K key,

Function<? super K, ? extends V> mappingFunction) {

...

if ((f = tabAt(tab, i = (n - 1) & h)) == null)

...

if ((val = mappingFunction.apply(key)) != null)

node = new Node<K,V>(h, key, val, null);

...

See docs.oracle.com/javase/tutorial/java/generics/upperBounded.html

‘extends’ is an upper-bounded wildcard that restricts the unknown type to be a specific type or a subtype of that type.

Page 15: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

class ConcurrentHashMap<K,V> ...

public V computeIfAbsent(K key,

Function<? super K, ? extends V> mappingFunction) {

...

if ((f = tabAt(tab, i = (n - 1) & h)) == null)

...

if ((val = mappingFunction.apply(key)) != null)

node = new Node<K,V>(h, key, val, null);

...

See en.wikipedia.org/wiki/Generics_in_Java#Type_wildcards

‘super’ & `extends’ play different roles in Java generics.

Page 16: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

class ConcurrentHashMap<K,V> ...

public V computeIfAbsent(K key,

Function<? super K, ? extends V> mappingFunction) {

...

if ((f = tabAt(tab, i = (n - 1) & h)) == null)

...

if ((val = mappingFunction.apply(key)) != null)

node = new Node<K,V>(h, key, val, null);

...

this::primeChecker

The function parameter is bound to this::primeChecker method reference.

Page 17: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• A Function applies a computation on one parameter & returns a result, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

class ConcurrentHashMap<K,V> ...

public V computeIfAbsent(K key,

Function<? super K, ? extends V> mappingFunction) {

...

if ((f = tabAt(tab, i = (n - 1) & h)) == null)

...

if ((val = mappingFunction.apply(key)) != null)

node = new Node<K,V>(h, key, val, null);

...

The apply() method is replaced with the primeChecker() lambda function.

if ((val = primeChecker(key)) != null)

Page 18: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

List<Thread> threads = Arrays.asList(new Thread("Larry"),

new Thread("Curly"),

new Thread("Moe"));

threads.forEach(System.out::println);

threads.sort(Comparator.comparing(Thread::getName));

threads.forEach(System.out::println);

Overview of Common Functional Interfaces: Function

See github.com/douglascraigschmidt/LiveLessons/tree/master/Java8/ex5

Create a list of threads named after the three stooges

Page 19: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

List<Thread> threads = Arrays.asList(new Thread("Larry"),

new Thread("Curly"),

new Thread("Moe")));

threads.forEach(System.out::println);

threads.sort(Comparator.comparing(Thread::getName));

threads.forEach(System.out::println);

A method reference to a Function used to sort threads by name

Overview of Common Functional Interfaces: Function

See dzone.com/articles/java-8-comparator-how-to-sort-a-list

Page 20: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

List<Thread> threads = Arrays.asList(new Thread("Larry"),

new Thread("Curly"),

new Thread("Moe")));

threads.forEach(System.out::println);

threads.sort(Comparator.comparing(Thread::getName));

threads.forEach(System.out::println);

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

This method uses the Thread::getName method reference to impose a total ordering on some collection of objects.

Overview of Common Functional Interfaces: Function

See docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#comparing

Page 21: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

List<Thread> threads = Arrays.asList(new Thread("Larry"),

new Thread("Curly"),

new Thread("Moe")));

threads.forEach(System.out::println);

threads.sort(comparing(Thread::getName).reversed());

threads.forEach(System.out::println);

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

The Comparator interface also contains a default method that reverses the ordering of a comparator

Overview of Common Functional Interfaces: Function

See docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#reversed

Page 22: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

interface Comparator {

...

static <T, U extends Comparable<? super U>> Comparator<T>

comparing(Function<? super T, ? extends U> keyEx) {

return ((c1, c2) ->

keyEx.apply(c1)

.compareTo(keyEx.apply(c2));

}

...

Overview of Common Functional Interfaces: Function

See docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#comparing

Imposes a total ordering on a collection of objects

Page 23: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

interface Comparator {

...

static <T, U extends Comparable<? super U>> Comparator<T>

comparing(Function<? super T, ? extends U> keyEx) {

return ((c1, c2) ->

keyEx.apply(c1)

.compareTo(keyEx.apply(c2));

}

...

Overview of Common Functional Interfaces: Function

The comparing() method is passed a Function parameter called keyEx.

Page 24: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

The Thread::getName method reference is bound to the keyEx parameter.

interface Comparator {

...

static <T, U extends Comparable<? super U>> Comparator<T>

comparing(Function<? super T, ? extends U> keyEx) {

return ((c1, c2) ->

keyEx.apply(c1)

.compareTo(keyEx.apply(c2));

}

...

Thread::getName

Page 25: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

interface Comparator {

...

static <T, U extends Comparable<? super U>> Comparator<T>

comparing(Function<? super T, ? extends U> keyEx) {

return ((c1, c2) ->

keyEx.apply(c1)

.compareTo(keyEx.apply(c2));

}

Overview of Common Functional Interfaces: Function

c1 & c2 are thread objects being compared by sort().

Page 26: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

interface Comparator {

...

static <T, U extends Comparable<? super U>> Comparator<T>

comparing(Function<? super T, ? extends U> keyEx) {

return ((c1, c2) ->

keyEx.apply(c1)

.compareTo(keyEx.apply(c2));

}

...

Overview of Common Functional Interfaces: Function

The apply() method of the keyExfunction is used to compare strings.

Page 27: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• This example also shows a Function, e.g.,

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

The thread::getName method reference is called to compare two thread names.

c1.getName().compareTo(c2.getName())

interface Comparator {

...

static <T, U extends Comparable<? super U>> Comparator<T>

comparing(Function<? super T, ? extends U> keyEx) {

return ((c1, c2) ->

keyEx.apply(c1)

.compareTo(keyEx.apply(c2));

}

...

Page 28: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• It’s also possible to compose functions.

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

class HtmlTagMaker {

static String addLessThan(String t) { return "<" + t; }

static String addGreaterThan(String t) { return t + ">"; }

}

Function<String, String> lessThan = HtmlTagMaker::addLessThan;

Function<String, String> tagger = lessThan

.andThen(HtmlTagMaker::addGreaterThan);

System.out.println(tagger.apply("HTML") + tagger.apply("BODY")

+ tagger.apply("/BODY") + tagger.apply("/HTML"));

}

These methods prepend ‘<‘ & append ‘>‘ to a string, respectively

Page 29: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• It’s also possible to compose functions.

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

class HtmlTagMaker {

static String addLessThan(String t) { return "<" + t; }

static String addGreaterThan(String t) { return t + ">"; }

}

Function<String, String> lessThan = HtmlTagMaker::addLessThan;

Function<String, String> tagger = lessThan

.andThen(HtmlTagMaker::addGreaterThan);

System.out.println(tagger.apply("HTML") + tagger.apply("BODY")

+ tagger.apply("/BODY") + tagger.apply("/HTML"));

}

These functions prepend ‘<‘ & append ‘>‘ to a string

Page 30: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• It’s also possible to compose functions.

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

See docs.oracle.com/javase/8/docs/api/java/util/function/Function.html#andThen

class HtmlTagMaker {

static String addLessThan(String t) { return "<" + t; }

static String addGreaterThan(String t) { return t + ">"; }

}

Function<String, String> lessThan = HtmlTagMaker::addLessThan;

Function<String, String> tagger = lessThan

.andThen(HtmlTagMaker::addGreaterThan);

System.out.println(tagger.apply("HTML") + tagger.apply("BODY")

+ tagger.apply("/BODY") + tagger.apply("/HTML"));

}

This method composes two functions!

Page 31: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming

• It’s also possible to compose functions.

• public interface Function<T, R> { R apply(T t); }

Overview of Common Functional Interfaces: Function

See docs.oracle.com/javase/8/docs/api/java/util/function/Function.html#andThen

class HtmlTagMaker {

static String addLessThan(String t) { return "<" + t; }

static String addGreaterThan(String t) { return t + ">"; }

}

Function<String, String> lessThan = HtmlTagMaker::addLessThan;

Function<String, String> tagger = lessThan

.andThen(HtmlTagMaker::addGreaterThan);

System.out.println(tagger.apply("HTML") + tagger.apply("BODY")

+ tagger.apply("/BODY") + tagger.apply("/HTML"));

}

Prints “<HTML><BODY></BODY></HTML>”

Page 32: Java 8 Functional Interfaces - Vanderbilt Universityschmidt/cs891f/2019-PDFs/java-func-inf-pt… · Learning Objectives in This Lesson •Recognize foundational functional programming