KEMBAR78
java 8 Hands on Workshop | PPT
Java 8 Hands on Workshop
FIRST Robotics Training
July 12, 2017
Jeanne Boyarsky
Twitter @jeanneboyarsky
Blog: http://www.selikoff.net
Disclaimer: Some of this material is copyright of Jeanne
Boyarsky, Scott Selikoff and/or Wiley Publishing
Twitter: @jeanneboyarsky
This PowerPoint is part of a hands
on workshop for teaching fluency
with Java 8 stream basics.
Twitter: @jeanneboyarsky
Pre-req:
Basic Java knowledge is required. If you can
implement this method using a loop, you
are good:
public int countStringsThatAreFourChars(
List<String> list) {
}
Groovy vs Java
Twitter: @jeanneboyarsky
print(
list
.grep{ j -> j.disabled }
.collect { j-> j.name }
)
list.stream()
.filter(j -> j.disabled)
.map(j -> j.name)
.forEach(
System.out::println);
Twitter: @jeanneboyarsky
TryYourIde.java
(5 mins)
• Local IDE
or
• https://www.compilejava.net
https://github.com/boyarsky/java-8-
streams-by-puzzles
Run src/TryYourIde class
Prints Do stuff and Do more stuff
Twitter: @jeanneboyarsky
Lambda vs Boilerplate
filter(j -> ! j.disabled)
filter(new Predicate<Job>() {
public boolean test(Job j) {
return ! j.disabled;
}
})
Twitter: @jeanneboyarsky
Basic Lambdas
Twitter: @jeanneboyarsky
Full Lambda Syntax
Java 8 Lambda Syntax Rules
Must have parens
unless exactly one
parameter
If listing type, must
be consistent
If multiple
statements: requires
braces, return and
semicolon
Twitter: @jeanneboyarsky
• () -> true
• a -> a.startsWith("test")
• (String a) ->
a.startsWith("test")
• (a, b) ->
a.startsWith("test")
• (String a, String b) ->
{ return
a.startsWith("test"); }
What’s wrong?
Twitter: @jeanneboyarsky
• a, b -> a.startsWith("test")
• a -> { a.startsWith("test"); }
• a -> { return a.startsWith("test") }
• (String a, b) -> a.startsWith("test")
• -> a.startsWith("test”)
Using variables
interface Gorilla { String move(); }
class GorillaFamily {
String walk = "walk";
void everyonePlay(boolean baby) {
String approach = "amble";
//approach = "run";
play(() -> walk);
play(() -> baby ? "hitch a ride" : "run");
play(() -> approach);
}
void play(Gorilla g) {
g.move();
}
}
1) Instance var
2) Class var
3) Effectively final
method param
or local var
Twitter: @jeanneboyarsky
LambdaFillInTheBlanks.java
(10-15 mins)
Easy - Fill in the blank so prints
out the numbers less than 3:
Stream.of(1, 2, 3, 5, 8)
.filter(__________)
.forEach(System.out::println);
Easy - Fill in the blank so prints out the
animals that are 4 characters in length:
Stream.of("cat", "dot", "fish", "rabbit")
.filter((p) -> { ___________ })
.forEach(System.out::println);
Medium - Fill in the blank so
prints the number 1:
long count = Stream.of(
"IBM", "Oracle", "Pivotal")
.filter(___________________)
.count();
System.out.println(count);
Twitter: @jeanneboyarsky
Challenge - How many
ways can you write a
lambda that takes one
String parameter named
“s” and returns the result of
s.isEmpty()?
Predicate?
Twitter: @jeanneboyarsky
Find the Functional Interface(s)
interface Slower {
double getCrawlSpeed();
String toString();
default int getSlowestSpeed() { return 0; }
static int getFastestSpeed() { return 10; }
}
interface Swimmer {
double getSwimSpeed();
}
interface Faster extends Slower {
double getFasterSpeed();
}
Twitter: @jeanneboyarsky
Common Functional Interface(s)
+ existing
interfaces
like
Comparable
Twitter: @jeanneboyarsky
FunctionalInterfacesFillInTheBlanks.java
(10-15 mins)
Twitter: @jeanneboyarsky
Easy: Predicate<String> p = s -> s.isEmpty();
Easy: Function<String, Integer> f = ________________;
Medium: Consumer<Double> c = ________________;
Hard: Supplier<Integer> s = _______________;
Challenge: How many ways can you fill in this blank?
_____________ ex = x -> "".equals(x.get(0));
Parts of a Stream Pipeline
Twitter: @jeanneboyarsky
Example of a Stream Pipeline
Twitter: @jeanneboyarsky
List<String> filtered = new ArrayList<>();
for (String name : list) {
if (name.length() == 4)
filtered.add(name);
}
Collections.sort(filtered);
List<String> result = filtered.subList(0, 2);
for (String name : result)
System.out.println(name);
Comparing code
list.stream()
.filter(n -> n.length() == 4)
.sorted().limit(2)
.forEach(System.out::println);
Twitter: @jeanneboyarsky
Example of a Chain
Twitter: @jeanneboyarsky
What happens if missing?
• If no source?
• If no intermediate operations?
• If no terminal operation?
Twitter: @jeanneboyarsky
Creating a Finite Stream
Stream<String> empty = Stream.empty();
Stream<Integer> singleElement =
Stream.of(1);
Stream<Integer> fromArray =
Stream.of(1, 2, 3);
List<String> list =
Arrays.asList("a", "b", "c");
Stream<String> fromList = list.stream();
Twitter: @jeanneboyarsky
Creating an Infinite Stream
Stream<Double> randoms =
Stream.generate(Math::random);
Stream<Integer> oddNumbers =
Stream.iterate(1, n -> n + 2);
Twitter: @jeanneboyarsky
Terminal Operations
Twitter: @jeanneboyarsky
Puzzle – No Intermediate Operations
(10 mins)
Twitter: @jeanneboyarsky
Easy:
Using the puzzle 1 handouts, arrange so the code
prints
true true 3
boolean b1 = ______.___________;
boolean b2 = ________.__________;
long l = ________.________;
System.out.println(b1 + " " + b2 + " " + l);
TranslateSearch.java
(5-10 mins)
Twitter: @jeanneboyarsky
Easy:
Translate this method to a one liner using
streams and lambdas:
private static boolean isZeroInList(
List<BigDecimal> list) {
for (BigDecimal decimal : list) {
if (decimal.equals(BigDecimal.ZERO))
return true;
}
return false;
}
Medium: How might you format the code to make it
easier to read?
Intermediate Operations
filter(p -> p.isEmpty())
limit(3)
skip(2)
map(x -> x.size())
distinct()
sorted()
sorted((a,b) -> a.compareTo(b))
peek(x -> System.out.println(x))
Twitter: @jeanneboyarsky
Puzzle – Intermediate Operations
(10 mins)
Twitter: @jeanneboyarsky
Medium:
Using the puzzle 2 handouts, arrange so the
code prints: true false 3
UnaryOperator<Integer> op = x -> x + 1;
Predicate<Integer> pred = x -> x > 5;
boolean b1 = Stream.iterate(1, op). ______. ______;
boolean b2 = Stream.iterate(1, op)
. ______. ______. ______;
long l = Stream.generate(() -> 1). ______. ______;
System.out.println(b1 + " " + b2 + " " + l);
Challenge: Why are there two correct answers?
CountMatches.java
(10-15 mins)
Twitter: @jeanneboyarsky
Easy:
Translate this method to a one liner using
streams and lambdas: (expected output is 1 and 0)
private static long numberMatches(List<String> list) {
long count = 0;
for (String string : list) {
if (string.contains("g"))
count++;
}
return count;
}
Challenge: Refactor the code so you can pass the
lambda as a method parameter.
MoreLogic.java
(10 mins)
Twitter: @jeanneboyarsky
Medium:
Implement the method to print “walrus” using the logic
described:
public static void main(String[] args) {
List<String> matchingList = Arrays.asList(
"whale", "dolphin", "whale”, "manatee",
"orca", "walrus", "calf");
printMe(matchingList);
}
private static void printMe(List<String> list) {
// Print the third distinct element alphabetically
// that is over 4 characters long
}
Hard: Write “the old way”
Optional
Twitter: @jeanneboyarsky
Optional APIs
Twitter: @jeanneboyarsky
Optional Terminal Operations
Twitter: @jeanneboyarsky
Puzzle – Optional
Twitter: @jeanneboyarsky
Hard:
Using the puzzle 3 handouts, arrange so the
code prints: 1 2 -1
Optional<Integer> o1 = Stream.generate(() -> 1)
. ______;
Optional<Integer> o2 = Stream.iterate(1, x -> x + 1)
. ______. ______. ______;
Optional<Integer> o3 = Stream.iterate(1, x -> x + 1)
. ______. ______. ______;
System.out.println(o1.orElse(-1) + " "
+ o2.orElse(-1) + " " + o3.orElse(-1));
Challenge: Why are there four correct answers?
Collectors
• collect(Collectors.toList())
• collect(Collectors.toSet())
• collect(Collectors.toMap(
keyFunction, valueFunction))
• collect(Collectors.groupingBy(func))
• collect(Collectors.partitioningBy(func))
• collect(Collectors.joining())
• collect(Collectors.joining(”, "))
Twitter: @jeanneboyarsky
Printing a Stream
Twitter: @jeanneboyarsky
Squares.java
(5-10 mins)
Twitter: @jeanneboyarsky
Easy:
Translate this method to a one liner using
streams and lambdas:
private static List<String> convert(List<Integer> list) {
List<String> result = new ArrayList<>();
for (Integer number : list) {
if (number % 2 == 0)
result.add(number + "*" + number + "=" + (number *
number));
}
return result;
}
Challenge: Can you figure out how to make the return
type a LinkedList?
OddsAndEvens.java
(10 mins)
Twitter: @jeanneboyarsky
Medium:
Implement this method using streams and lambdas.
(Remember % is the modulus operator).
public static void main(String[] args) {
System.out.println(split(Arrays.asList(1, 4, 8,
13)));
System.out.println(split(Arrays.asList(1, 3)));
}
private static
Map<Boolean,List<Integer>> split(List<Integer> list) {
// partition the list into odds and evens
}
Hard: Change partioningBy to groupingBy. What’s the
difference?
Challenge: Implement this method without streams.
Method References
Infer lambdas by passing parameters for:
• Static methods
• Constructors
• Instance methods on the lambda param
• Instance methods on a particular instance
Twitter: @jeanneboyarsky
Static References
Twitter: @jeanneboyarsky
Java 7 new Consumer<List<Integer>>() {
public void accept(List<Integer> l) {
Collections.sort(l);
}
}
Lambda
l -> Collections.sort(l)
Method Reference
Collections::sort;
Constructor References
Twitter: @jeanneboyarsky
Java 7 new Supplier<ArrayList>() {
public ArrayList get() {
return new ArrayList();
}
}
Lambda
() -> new ArrayList()
Method Reference
ArrayList::new
Note: passing “zero length param list
Instance References
Twitter: @jeanneboyarsky
Java 7 new Predicate<String>() {
public boolean test(String s) {
return s.isEmpty();
}
}
Lambda s -> s.isEmpty()
Method Reference String::isEmpty
Instance References 2
Twitter: @jeanneboyarsky
Java 7 new Predicate<String>() {
public boolean test(String s) {
return str.startsWith(s);
}
}
Lambda
s -> str.startsWith(s)
Method Reference
str::startsWith
Assume: String str = "abc";
MethodReferencesFillInTheBlanks.java
(10-15 mins)
Easy: Fill in the blank to print with a lambda and method
reference.
Stream.of(“", "b", ”bc”).forEach(_________);
Hard: How many of these can you use a method
reference to fill in the blank? (the string is empty, the
string is not empty, the string ends with ‘c’)
Stream.of(“", "b", ”bc").filter(_________)
.forEach(System.out::println);
Twitter: @jeanneboyarsky
Next Steps to Learn
• Primitive streams
• Reduce()
• Summary Statistics
• Advanced collect()
Twitter: @jeanneboyarsky
Questions
?
Twitter: @jeanneboyarsky

java 8 Hands on Workshop

  • 1.
    Java 8 Handson Workshop FIRST Robotics Training July 12, 2017 Jeanne Boyarsky Twitter @jeanneboyarsky Blog: http://www.selikoff.net
  • 2.
    Disclaimer: Some ofthis material is copyright of Jeanne Boyarsky, Scott Selikoff and/or Wiley Publishing Twitter: @jeanneboyarsky This PowerPoint is part of a hands on workshop for teaching fluency with Java 8 stream basics.
  • 3.
    Twitter: @jeanneboyarsky Pre-req: Basic Javaknowledge is required. If you can implement this method using a loop, you are good: public int countStringsThatAreFourChars( List<String> list) { }
  • 4.
    Groovy vs Java Twitter:@jeanneboyarsky print( list .grep{ j -> j.disabled } .collect { j-> j.name } ) list.stream() .filter(j -> j.disabled) .map(j -> j.name) .forEach( System.out::println);
  • 5.
    Twitter: @jeanneboyarsky TryYourIde.java (5 mins) •Local IDE or • https://www.compilejava.net https://github.com/boyarsky/java-8- streams-by-puzzles Run src/TryYourIde class Prints Do stuff and Do more stuff
  • 6.
    Twitter: @jeanneboyarsky Lambda vsBoilerplate filter(j -> ! j.disabled) filter(new Predicate<Job>() { public boolean test(Job j) { return ! j.disabled; } })
  • 7.
  • 8.
  • 9.
    Java 8 LambdaSyntax Rules Must have parens unless exactly one parameter If listing type, must be consistent If multiple statements: requires braces, return and semicolon Twitter: @jeanneboyarsky • () -> true • a -> a.startsWith("test") • (String a) -> a.startsWith("test") • (a, b) -> a.startsWith("test") • (String a, String b) -> { return a.startsWith("test"); }
  • 10.
    What’s wrong? Twitter: @jeanneboyarsky •a, b -> a.startsWith("test") • a -> { a.startsWith("test"); } • a -> { return a.startsWith("test") } • (String a, b) -> a.startsWith("test") • -> a.startsWith("test”)
  • 11.
    Using variables interface Gorilla{ String move(); } class GorillaFamily { String walk = "walk"; void everyonePlay(boolean baby) { String approach = "amble"; //approach = "run"; play(() -> walk); play(() -> baby ? "hitch a ride" : "run"); play(() -> approach); } void play(Gorilla g) { g.move(); } } 1) Instance var 2) Class var 3) Effectively final method param or local var Twitter: @jeanneboyarsky
  • 12.
    LambdaFillInTheBlanks.java (10-15 mins) Easy -Fill in the blank so prints out the numbers less than 3: Stream.of(1, 2, 3, 5, 8) .filter(__________) .forEach(System.out::println); Easy - Fill in the blank so prints out the animals that are 4 characters in length: Stream.of("cat", "dot", "fish", "rabbit") .filter((p) -> { ___________ }) .forEach(System.out::println); Medium - Fill in the blank so prints the number 1: long count = Stream.of( "IBM", "Oracle", "Pivotal") .filter(___________________) .count(); System.out.println(count); Twitter: @jeanneboyarsky Challenge - How many ways can you write a lambda that takes one String parameter named “s” and returns the result of s.isEmpty()?
  • 13.
  • 14.
    Find the FunctionalInterface(s) interface Slower { double getCrawlSpeed(); String toString(); default int getSlowestSpeed() { return 0; } static int getFastestSpeed() { return 10; } } interface Swimmer { double getSwimSpeed(); } interface Faster extends Slower { double getFasterSpeed(); } Twitter: @jeanneboyarsky
  • 15.
    Common Functional Interface(s) +existing interfaces like Comparable Twitter: @jeanneboyarsky
  • 16.
    FunctionalInterfacesFillInTheBlanks.java (10-15 mins) Twitter: @jeanneboyarsky Easy:Predicate<String> p = s -> s.isEmpty(); Easy: Function<String, Integer> f = ________________; Medium: Consumer<Double> c = ________________; Hard: Supplier<Integer> s = _______________; Challenge: How many ways can you fill in this blank? _____________ ex = x -> "".equals(x.get(0));
  • 17.
    Parts of aStream Pipeline Twitter: @jeanneboyarsky
  • 18.
    Example of aStream Pipeline Twitter: @jeanneboyarsky
  • 19.
    List<String> filtered =new ArrayList<>(); for (String name : list) { if (name.length() == 4) filtered.add(name); } Collections.sort(filtered); List<String> result = filtered.subList(0, 2); for (String name : result) System.out.println(name); Comparing code list.stream() .filter(n -> n.length() == 4) .sorted().limit(2) .forEach(System.out::println); Twitter: @jeanneboyarsky
  • 20.
    Example of aChain Twitter: @jeanneboyarsky
  • 21.
    What happens ifmissing? • If no source? • If no intermediate operations? • If no terminal operation? Twitter: @jeanneboyarsky
  • 22.
    Creating a FiniteStream Stream<String> empty = Stream.empty(); Stream<Integer> singleElement = Stream.of(1); Stream<Integer> fromArray = Stream.of(1, 2, 3); List<String> list = Arrays.asList("a", "b", "c"); Stream<String> fromList = list.stream(); Twitter: @jeanneboyarsky
  • 23.
    Creating an InfiniteStream Stream<Double> randoms = Stream.generate(Math::random); Stream<Integer> oddNumbers = Stream.iterate(1, n -> n + 2); Twitter: @jeanneboyarsky
  • 24.
  • 25.
    Puzzle – NoIntermediate Operations (10 mins) Twitter: @jeanneboyarsky Easy: Using the puzzle 1 handouts, arrange so the code prints true true 3 boolean b1 = ______.___________; boolean b2 = ________.__________; long l = ________.________; System.out.println(b1 + " " + b2 + " " + l);
  • 26.
    TranslateSearch.java (5-10 mins) Twitter: @jeanneboyarsky Easy: Translatethis method to a one liner using streams and lambdas: private static boolean isZeroInList( List<BigDecimal> list) { for (BigDecimal decimal : list) { if (decimal.equals(BigDecimal.ZERO)) return true; } return false; } Medium: How might you format the code to make it easier to read?
  • 27.
    Intermediate Operations filter(p ->p.isEmpty()) limit(3) skip(2) map(x -> x.size()) distinct() sorted() sorted((a,b) -> a.compareTo(b)) peek(x -> System.out.println(x)) Twitter: @jeanneboyarsky
  • 28.
    Puzzle – IntermediateOperations (10 mins) Twitter: @jeanneboyarsky Medium: Using the puzzle 2 handouts, arrange so the code prints: true false 3 UnaryOperator<Integer> op = x -> x + 1; Predicate<Integer> pred = x -> x > 5; boolean b1 = Stream.iterate(1, op). ______. ______; boolean b2 = Stream.iterate(1, op) . ______. ______. ______; long l = Stream.generate(() -> 1). ______. ______; System.out.println(b1 + " " + b2 + " " + l); Challenge: Why are there two correct answers?
  • 29.
    CountMatches.java (10-15 mins) Twitter: @jeanneboyarsky Easy: Translatethis method to a one liner using streams and lambdas: (expected output is 1 and 0) private static long numberMatches(List<String> list) { long count = 0; for (String string : list) { if (string.contains("g")) count++; } return count; } Challenge: Refactor the code so you can pass the lambda as a method parameter.
  • 30.
    MoreLogic.java (10 mins) Twitter: @jeanneboyarsky Medium: Implementthe method to print “walrus” using the logic described: public static void main(String[] args) { List<String> matchingList = Arrays.asList( "whale", "dolphin", "whale”, "manatee", "orca", "walrus", "calf"); printMe(matchingList); } private static void printMe(List<String> list) { // Print the third distinct element alphabetically // that is over 4 characters long } Hard: Write “the old way”
  • 31.
  • 32.
  • 33.
  • 34.
    Puzzle – Optional Twitter:@jeanneboyarsky Hard: Using the puzzle 3 handouts, arrange so the code prints: 1 2 -1 Optional<Integer> o1 = Stream.generate(() -> 1) . ______; Optional<Integer> o2 = Stream.iterate(1, x -> x + 1) . ______. ______. ______; Optional<Integer> o3 = Stream.iterate(1, x -> x + 1) . ______. ______. ______; System.out.println(o1.orElse(-1) + " " + o2.orElse(-1) + " " + o3.orElse(-1)); Challenge: Why are there four correct answers?
  • 35.
    Collectors • collect(Collectors.toList()) • collect(Collectors.toSet()) •collect(Collectors.toMap( keyFunction, valueFunction)) • collect(Collectors.groupingBy(func)) • collect(Collectors.partitioningBy(func)) • collect(Collectors.joining()) • collect(Collectors.joining(”, ")) Twitter: @jeanneboyarsky
  • 36.
  • 37.
    Squares.java (5-10 mins) Twitter: @jeanneboyarsky Easy: Translatethis method to a one liner using streams and lambdas: private static List<String> convert(List<Integer> list) { List<String> result = new ArrayList<>(); for (Integer number : list) { if (number % 2 == 0) result.add(number + "*" + number + "=" + (number * number)); } return result; } Challenge: Can you figure out how to make the return type a LinkedList?
  • 38.
    OddsAndEvens.java (10 mins) Twitter: @jeanneboyarsky Medium: Implementthis method using streams and lambdas. (Remember % is the modulus operator). public static void main(String[] args) { System.out.println(split(Arrays.asList(1, 4, 8, 13))); System.out.println(split(Arrays.asList(1, 3))); } private static Map<Boolean,List<Integer>> split(List<Integer> list) { // partition the list into odds and evens } Hard: Change partioningBy to groupingBy. What’s the difference? Challenge: Implement this method without streams.
  • 39.
    Method References Infer lambdasby passing parameters for: • Static methods • Constructors • Instance methods on the lambda param • Instance methods on a particular instance Twitter: @jeanneboyarsky
  • 40.
    Static References Twitter: @jeanneboyarsky Java7 new Consumer<List<Integer>>() { public void accept(List<Integer> l) { Collections.sort(l); } } Lambda l -> Collections.sort(l) Method Reference Collections::sort;
  • 41.
    Constructor References Twitter: @jeanneboyarsky Java7 new Supplier<ArrayList>() { public ArrayList get() { return new ArrayList(); } } Lambda () -> new ArrayList() Method Reference ArrayList::new Note: passing “zero length param list
  • 42.
    Instance References Twitter: @jeanneboyarsky Java7 new Predicate<String>() { public boolean test(String s) { return s.isEmpty(); } } Lambda s -> s.isEmpty() Method Reference String::isEmpty
  • 43.
    Instance References 2 Twitter:@jeanneboyarsky Java 7 new Predicate<String>() { public boolean test(String s) { return str.startsWith(s); } } Lambda s -> str.startsWith(s) Method Reference str::startsWith Assume: String str = "abc";
  • 44.
    MethodReferencesFillInTheBlanks.java (10-15 mins) Easy: Fillin the blank to print with a lambda and method reference. Stream.of(“", "b", ”bc”).forEach(_________); Hard: How many of these can you use a method reference to fill in the blank? (the string is empty, the string is not empty, the string ends with ‘c’) Stream.of(“", "b", ”bc").filter(_________) .forEach(System.out::println); Twitter: @jeanneboyarsky
  • 45.
    Next Steps toLearn • Primitive streams • Reduce() • Summary Statistics • Advanced collect() Twitter: @jeanneboyarsky
  • 46.

Editor's Notes

  • #5 Key points Quick preview of streams Syntax and flow will come naturally by the end of the session Note that Java and Groovy use similar but different syntax/method names (aka be careful if primarily a Groovy developer) Not expected to understand the details/syntax Appreciate that there isn’t a loop or if statement. Just the declarative statements.
  • #6 Goal of this “slide” is to ensure all attendees are able to run a Java 8 program – either in their local IDE or online. Online IDEs: compilejava.net – easiest to use – make sure not to have package names ideone.com – has ads, remove public keyword from class to work https://commons.wikimedia.org/wiki/File:Interactive_icon.svg Image from https://commons.wikimedia.org/wiki/File:Gnome-edit-paste.svg
  • #11 Answers: Need parens since two parameters Need return statement since braces Need semi-colon since braces Need type for neither or both params Need parameter https://goo.gl/images/5X5VL2
  • #13 Answers: Easy: n -&amp;gt; n &amp;lt; 3 Easy: return p.length() == 4; Medium: There are many correct answers such as n -&amp;gt; n.startsWith(&amp;quot;I&amp;quot;) Challenge: I can think of 6 ways: Predicate&amp;lt;String&amp;gt; p1 = s -&amp;gt; s.isEmpty(); Predicate&amp;lt;String&amp;gt; p2 = (s) -&amp;gt; s.isEmpty(); Predicate&amp;lt;String&amp;gt; p3 = (String s) -&amp;gt; s.isEmpty(); Predicate&amp;lt;String&amp;gt; p4 = s -&amp;gt; { return s.isEmpty(); }; Predicate&amp;lt;String&amp;gt; p5 = (s) -&amp;gt; { return s.isEmpty(); }; Predicate&amp;lt;String&amp;gt; p6 = (String s) -&amp;gt; { return s.isEmpty(); };
  • #15 Key Points Swimmer is a functional interface Only one method and it is abstract Slower is a functional interface getCrawlSpeed() is abstract toString() is not abstract because inherited from Object getSlowestSpeed() and getFastestSpeed() are not abstract Faster is not a functional interface It has one abstract method declared but inherits another
  • #16 Key points Don’t need to memorize this. Note that the common combinations exist. If writing code that uses streams, you don’t actually need to know the functional interface name. Compiler infers it. Do need to know these methods if writing libraries
  • #17 Many answers such as: Easy: s -&amp;gt; s.isEmpty() Easy: s -&amp;gt; s.length() Medium: d -&amp;gt; System.out.println(d) Hard: () -&amp;gt; new Random().nextInt() or () -&amp;gt; 1 Challenge: I can find six Predicate&amp;lt;List&amp;lt;String&amp;gt;&amp;gt; Function&amp;lt;List&amp;lt;String&amp;gt;, Boolean&amp;gt; Consumer&amp;lt;List&amp;lt;String&amp;gt;&amp;gt; Predicate&amp;lt;Map&amp;lt;Integer, String&amp;gt;&amp;gt; Function&amp;lt;Map&amp;lt;Integer, String&amp;gt;, Boolean&amp;gt; Consumer&amp;lt;Map&amp;lt;Integer, String&amp;gt;&amp;gt;
  • #18 Go over the three parts of a stream pipeline
  • #19 Walk through the factory example
  • #20 Compare loop to lambda code
  • #21 Map the previous example to the three parts of a pipeline
  • #22 Answers: If no source, can’t start If not intermediate operations ok. If no terminal operations, the stream isn’t run.
  • #26 Answer: Using the puzzle 1 handouts, arrange so the code prints true true 3 boolean b1 = Stream.empty().allMatch(p -&amp;gt; true); boolean b2 = Stream.generate(String::new).anyMatch(p -&amp;gt; true); long l = Stream.of(1,2,3).count(); System.out.println(b1 + &amp;quot; &amp;quot; + b2 + &amp;quot; &amp;quot; + l); Or boolean b1 = Stream.generate(String::new).anyMatch(p -&amp;gt; true); boolean b2 = Stream.empty().allMatch(p -&amp;gt; true); long l = Stream.of(1,2,3).count(); System.out.println(b1 + &amp;quot; &amp;quot; + b2 + &amp;quot; &amp;quot; + l);
  • #27 Answer: return list.stream().anyMatch(b -&amp;gt; BigDecimal.ZERO.equals(b)); return list.stream() .anyMatch(b -&amp;gt; BigDecimal.ZERO.equals(b));
  • #29 Answer: UnaryOperator&amp;lt;Integer&amp;gt; op = x -&amp;gt; x + 1; Predicate&amp;lt;Integer&amp;gt; pred = x -&amp;gt; x &amp;gt; 5; boolean b1 = Stream.iterate(1, op).skip(2).anyMatch(pred); boolean b2 = Stream.iterate(1, op).limit(2).skip(1).allMatch(pred); long l = Stream.generate(() -&amp;gt; 1).limit(3).count(); System.out.println(b1 + &amp;quot; &amp;quot; + b2 + &amp;quot; &amp;quot; + l); Or UnaryOperator&amp;lt;Integer&amp;gt; op = x -&amp;gt; x + 1; Predicate&amp;lt;Integer&amp;gt; pred = x -&amp;gt; x &amp;gt; 5; boolean b1 = Stream.iterate(1, op).skip(1).anyMatch(pred); boolean b2 = Stream.iterate(1, op).skip(2).limit(2).allMatch(pred); long l = Stream.generate(() -&amp;gt; 1).limit(3).count(); System.out.println(b1 + &amp;quot; &amp;quot; + b2 + &amp;quot; &amp;quot; + l);
  • #30 Answer: return list.stream().filter(s -&amp;gt; s.contains(&amp;quot;g&amp;quot;)).count(); private static long numberMatches(List&amp;lt;String&amp;gt; list, Predicate&amp;lt;String&amp;gt; pred) { return list.stream().filter(pred).count(); }
  • #31 Answer Medium: list.stream().filter(s -&amp;gt; s.length() &amp;gt; 4) .sorted() .distinct() .skip(2) .limit(1) .forEach(n -&amp;gt; System.out.println(n)); Hard: TreeSet&amp;lt;String&amp;gt; set = new TreeSet&amp;lt;&amp;gt;(list); List&amp;lt;String&amp;gt; sortedList = new ArrayList&amp;lt;&amp;gt;(); for (String string : set) { if (string.length() &amp;gt; 4) { sortedList.add(string); } } System.out.println(sortedList.get(2));
  • #35 Answer: Optional&amp;lt;Integer&amp;gt; o1 = Stream.generate(() -&amp;gt; 1).findAny(); Optional&amp;lt;Integer&amp;gt; o2 = Stream.iterate(1, x -&amp;gt; x + 1).map(x -&amp;gt; x * 2).limit(3).max(); Optional&amp;lt;Integer&amp;gt; o3 = Stream.iterate(1, x -&amp;gt; x + 1).limit(5).filter(x -&amp;gt; x &amp;gt; 8).findFirst(); Or Optional&amp;lt;Integer&amp;gt; o1 = Stream.generate(() -&amp;gt; 1).findFirst(); Optional&amp;lt;Integer&amp;gt; o2 = Stream.iterate(1, x -&amp;gt; x + 1).map(x -&amp;gt; x * 2).limit(3).max(); Optional&amp;lt;Integer&amp;gt; o3 = Stream.iterate(1, x -&amp;gt; x + 1).limit(5).filter(x -&amp;gt; x &amp;gt; 8).findAny(); Or Optional&amp;lt;Integer&amp;gt; o1 = Stream.generate(() -&amp;gt; 1).findAny(); Optional&amp;lt;Integer&amp;gt; o2 = Stream.iterate(1, x -&amp;gt; x + 1).limit(3).map(x -&amp;gt; x * 2).max(); Optional&amp;lt;Integer&amp;gt; o3 = Stream.iterate(1, x -&amp;gt; x + 1).limit(5).filter(x -&amp;gt; x &amp;gt; 8).findFirst(); Or Optional&amp;lt;Integer&amp;gt; o1 = Stream.generate(() -&amp;gt; 1).findFirst(); Optional&amp;lt;Integer&amp;gt; o2 = Stream.iterate(1, x -&amp;gt; x + 1).limit(3). map(x -&amp;gt; x * 2).max(); Optional&amp;lt;Integer&amp;gt; o3 = Stream.iterate(1, x -&amp;gt; x + 1).limit(5).filter(x -&amp;gt; x &amp;gt; 8).findAny(); For the first line, findAny() or findFirst() give the same result because all the entries are 1. For the last line, either gives the same result because the stream is empty at that point. Also, the order of map and limit doesn’t matter since they don’t interrelate. System.out.println(o1.orElse(-1) + &amp;quot; &amp;quot; + o2.orElse(-1) + &amp;quot; &amp;quot; + o3.orElse(-1));
  • #38 Answer: return list.stream() .filter(n -&amp;gt; n%2 ==0) .map(n -&amp;gt; n + &amp;quot;*&amp;quot; + n + &amp;quot;=&amp;quot; + (n*n)) .collect(Collectors.toList()); Challenge answer: return list.stream() .filter(n -&amp;gt; n%2 ==0) .map(n -&amp;gt; n + &amp;quot;*&amp;quot; + n + &amp;quot;=&amp;quot; + (n*n)) .collect(Collectors.toCollection(LinkedList::new));
  • #39 Answer Easy: return list.stream().collect(Collectors.partitioningBy(x -&amp;gt; x % 2 == 0)); Hard: Grouping by doesn’t include the key if there are no matches Challenge: Map&amp;lt;Boolean,List&amp;lt;Integer&amp;gt;&amp;gt; result = new HashMap&amp;lt;&amp;gt;(); result.put(Boolean.FALSE, new ArrayList&amp;lt;&amp;gt;()); result.put(Boolean.TRUE, new ArrayList&amp;lt;&amp;gt;()); for (Integer integer : list) { boolean key = integer %2 == 0; result.get(key).add(integer); } return result;
  • #45 Answers: Easy: System.out::println and x -&amp;gt; System.out.println(x) Hard: One Stream.of(&amp;quot;&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;bc&amp;quot;).filter(String::isEmpty).forEach(System.out::println); String is not empty requires a lambda (or you to write a static method) because it uses an operator String ends with ‘c’ requires a lambda (or you to write a static method) because it uses a parameter