SAILING WITH JAVA 8 STREAMS
ocpjava.wordpress.com
Ganesh Samarthyam
Java
876
…
I am evolving…
Java 8: Latest (red-hot)
Recent addition:
lambdas
8
Greek characters
are scary!
He he, but lambdas
are fun, not scary
Java meets functional
programming (with lambdas)
Introducing our star
feature - lambda
functions
List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo");
Consumer<String> printString = string -> System.out.println(string);
strings.forEach(printString);
Lambda
functions!
But what are
lambdas?
Lambdas is just a fancy
name for functions
without a name!
Arrays.asList("eeny", "meeny", "miny", “mo”)
.forEach(string -> System.out.println(string));
Internal Iteration
List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo");
for(String string : strings) {
System.out.println(string);
}
External Iteration
Lambda
expression
You can use lambdas for
some amazing stuff
sediment
pre-
carbon
ultra-filter
post-
carbon
Filtered
water
E.g., you can compose lambda
functions as in pipes-and-filters
$ cat limerick.txt
There was a young lady of Niger
Who smiled as she rode on a tiger.
They returned from the ride
With the lady inside
And a smile on the face of the tiger.
$ cat limerick.txt | tr -cs "[:alpha:]" "n" | awk '{print
length(), $0}' | sort | uniq
1 a
2 as
2 of
2 on
3 And
3 Who
3 she
3 the
3 was
4 They
4 With
4 face
4 from
4 lady
4 ride
4 rode
5 Niger
5 There
5 smile
5 tiger
5 young
6 inside
6 smiled
8 returned
List<String> lines
= Files.readAllLines(Paths.get("./limerick.txt"), Charset.defaultCharset());
	 	 Map<Integer, List<String>> wordGroups
	 	 = lines.stream()
	 .map(line -> line.replaceAll("W", "n").split("n"))
	 .flatMap(Arrays::stream)
	 .sorted()
	 .distinct()
	 .collect(Collectors.groupingBy(String::length));
	 	 wordGroups.forEach( (count, words) -> {
	 	 words.forEach(word -> System.out.printf("%d %s %n", count, word));
	 	 });
1 a
2 as
2 of
2 on
3 And
3 Who
3 she
3 the
3 was
4 They
4 With
4 face
4 from
4 lady
4 ride
4 rode
5 Niger
5 There
5 smile
5 tiger
5 young
6 inside
6 smiled
8 returned
Lambdas & streams help in
productive programming!
public static void main(String []file) throws Exception {
// process each file passed as argument
// try opening the file with FileReader
try (FileReader inputFile = new FileReader(file[0])) {
int ch = 0;
while( (ch = inputFile.read()) != -1) {
// ch is of type int - convert it back to char
System.out.print( (char)ch );
}
}
// try-with-resources will automatically release FileReader object
}
public static void main(String []file) throws Exception {
Files.lines(Paths.get(file[0])).forEach(System.out::println);
}
Existing APIs are enriched with
lambdas and streams support
So, lets get our hands dirty
and start coding
interface LambdaFunction {
void call();
}
class FirstLambda {
public static void main(String []args) {
LambdaFunction lambdaFunction = () -> System.out.println("Hello world");
lambdaFunction.call();
}
}
Functional interface - provides
signature for lambda functions
Lambda function/expression
Call to the lambda
Prints “Hello world” on the console when executed
@FunctionalInterface
interface LambdaFunction {
void call();
}
Functional interface
Abstract method providing the signature of the
lambda function
Annotation to explicitly state that it is a functional
interface
arg -> System.out.println(arg)
System.out::println
Method references - “syntactic sugar” for
lambda functions
They “route” function parameters
Java 8 streams (and parallel streams):
Excellent example of applying functional
programming in practice
But what are streams?
Arrays.stream(Object.class.getMethods())
.map(method -> method.getName())
.distinct()
.forEach(System.out::println);
wait
equals
toString
hashCode
getClass
notify
notifyAll
Method[] objectMethods = Object.class.getMethods();
Stream<Method> objectMethodStream = Arrays.stream(objectMethods);
Stream<String> objectMethodNames
= objectMethodStream.map(method -> method.getName());
Stream<String> uniqueObjectMethodNames = objectMethodNames.distinct();
uniqueObjectMethodNames.forEach(System.out::println);
Arrays.stream(Object.class.getMethods())
.map(method -> method.getName())
.distinct()
.forEach(System.out::println);
Breaking up into separate
(looong) statements for our
understanding
stream pipeline
Stream	
source	
Intermediate	
opera1ons	
Terminal	
opera1on	
stream	
stream	
Examples:	
IntStream.range(),		
Arrays.stream()	
Examples:	
map(),	filter(),		
dis1nct(),	sorted()	
Examples:	
sum(),	collect(),		
forEach(),	reduce()
DoubleStream.	
of(1.0,	4.0,	9.0)		
map(Math::sqrt)		
.peek(System.out::
println)		
Stream		
Source	(with	
elements	1.0,	
4.0,	and	9.0)	
Intermediate	
Opera=on	1	
(maps	to	
element	values	
1.0,	2.0,	and	3.0)	
Intermediate	
Opera=on	2	
(prints	1.0,	2.0,	
and	3.0)	
.sum();		
Terminal	
Opera=on	
(returns	the	
sum	6.0)	
DoubleStream.of(1.0, 4.0, 9.0)
.map(Math::sqrt)
.peek(System.out::println)
.sum();
IntStream.range(1, 6)
You can use range or iterate
factory methods in the
IntStream interface
IntStream.iterate(1, i -> i + 1).limit(5)
1	 	2 	3 	4 	5	
1	 	4 	9 	16 		25	
map(i	->	i	*	i)	
IntStream.range(1, 5).map(i -> i * i).forEach(System.out::println);
Using streams instead of imperative for i = 1 to 5, print i * i
Stream.of (1, 2, 3, 4, 5)
.map(i -> i * i)
.peek(i -> System.out.printf("%d ", i))
.count();
prints: 1 4 9 16 25
stream can be
infinite
IntStream.iterate(0, i -> i + 2).forEach(System.out::println);
This code creates infinite stream of even numbers!
IntStream
.iterate(0, i -> i + 2)
.limit(5)
.forEach(System.out::println);
Using the “limit” function to limit the stream to 5 integers
IntStream chars = "bookkeep".chars();
System.out.println(chars.count());
chars.distinct().sorted().forEach(ch -> System.out.printf("%c ", ch));
Cannot “reuse” a stream; this code
throws IllegalStateException
Streams are lazy!
Files.lines(Paths.get("FileRead.java")).forEach(System.out::println);
This code prints the contents of
the file “FileRead.java” in the
current directory
Pattern.compile(" ").splitAsStream("java 8 streams").forEach(System.out::println);
This code splits the input string “java 8
streams” based on whitespace and hence
prints the strings “java”, “8”, and
“streams” on the console
new Random().ints().limit(5).forEach(System.out::println);
Generates 5 random integers and prints
them on the console
"hello".chars().sorted().forEach(ch -> System.out.printf("%c ", ch));
Extracts characters in the string “hello”,
sorts the chars and prints the chars
Parallel Streams
race conditions
deadlocks
I really really hate
concurrency problems
Parallel code
Serial code
Sometimes, dreams do come
true even at 86 :-)
So, keep dreaming till you
become 86!
long numOfPrimes = LongStream.rangeClosed(2, 100_000)
.filter(PrimeNumbers::isPrime)
.count();
System.out.println(numOfPrimes);
Prints 9592
2.510 seconds
Parallel code
Serial code
Let’s flip the switch by
calling parallel() function
long numOfPrimes = LongStream.rangeClosed(2, 100_000)
.parallel()
.filter(PrimeNumbers::isPrime)
.count();
System.out.println(numOfPrimes);
Prints 9592
1.235 seconds
Wow! That’s an awesome flip
switch!
Internally, parallel streams make
use of fork-join framework
import java.util.Arrays;
class StringConcatenator {
public static String result = "";
public static void concatStr(String str) {
result = result + " " + str;
}
}
class StringSplitAndConcatenate {
public static void main(String []args) {
String words[] = "the quick brown fox jumps over the lazy dog".split(" ");
Arrays.stream(words).forEach(StringConcatenator::concatStr);
System.out.println(StringConcatenator.result);
}
}
Gives wrong results with
with parallel() call
Adapt, learn functional
programming!
❖ Programming examples are
from our book:
❖ Oracle Certified Professional
Java SE 8 Programmer Exam
1Z0-809: A Comprehensive
OCPJP 8 Certification Guide,
S.G. Ganesh, Hari Kiran
Kumar, Tushar Sharma, Apress,
2016.
❖ Website: ocpjava.wordpress.com
Image credits
• http://www.wetplanetwhitewater.com/images/uploads/adam_mills_elliott82.jpg
• http://s.ecrater.com/stores/321182/53e46c705f68d_321182b.jpg
• http://img.viralpatel.net/2014/01/java-lambda-expression.png
• https://i.ytimg.com/vi/3C0R_fEXcYA/maxresdefault.jpg
• http://farm1.static.flickr.com/74/170765090_53762a686c.jpg
• http://www.monazu.com/wp-content/uploads/2012/06/ask-the-right-questions.jpg
• https://s-media-cache-ak0.pinimg.com/736x/43/42/8a/43428ac2c352166374d851e895ed5db1.jpg
• http://cdn.attackofthecute.com/August-17-2011-12-36-23-peekaboo-
kitty-46f32anul-131384-530-410.jpeg
• https://ludchurchmyblog.files.wordpress.com/2010/02/myths-legend-pictures-083.jpg
• http://www.youramazingplaces.com/wp-content/uploads/2013/06/Mauvoisin-Dam-
Switzerland-620x413.jpg
• http://www.welikeviral.com/files/2014/08/Image-914.jpg
• http://geekandpoke.typepad.com/.a/6a00d8341d3df553ef013485f6be4d970c-800wi
• https://qph.fs.quoracdn.net/main-qimg-56547c0506050206b50b80a268bf2a84
• https://i.ytimg.com/vi/kCVsKsgVhBA/maxresdefault.jpg
• http://i.livescience.com/images/i/000/022/395/original/man-dreams-bed.jpg
• https://static-secure.guim.co.uk/sys-images/Guardian/Pix/pictures/2012/11/26/1353952826063/Alarm-
clock-010.jpg
email sgganesh@gmail.com
website www.designsmells.com
twitter @GSamarthyam
linkedin bit.ly/sgganesh
slideshare slideshare.net/sgganesh

Sailing with Java 8 Streams