35
Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp [email protected]

Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp [email protected]

  • Upload
    lyquynh

  • View
    241

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Java 8 StreamsSaint Louis Java Users Group

8 January, 2015

Charles A Sharp [email protected]

Page 2: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

While adding lambda expressions to the language is a huge step forward, developers get their work done every day by using the core libraries, so the language evolution effort was paired with a library evolution effort so that users could start using the new features on day one. The centerpiece of the new library features is the Stream abstraction, which provides powerful facilities for aggregate operations on data sets, and has been deeply integrated with the existing collection classes as well as other JDK classes.

— State of the Lambda: Library Edition

Summary

Page 3: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com
Page 4: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

grep 'Error' /var/log/err_log | \

sed 's/^.*Error//' | \

sort | \

uniq -c > /tmp/error_count

Page 5: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

— Jennifer Egan, A Visit from the Goon Squad

“There are so many ways to go wrong," Lulu said. "All we've got are metaphors, and

they're never exactly right. You can't ever just Say. The. Thing.”

Page 6: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

In computer science, a stream is a sequence of data elements made available over time.

https://en.wikipedia.org/wiki/Stream_(computing)

In object-oriented programming, input streams are generally implemented as iterators.

.

.

.

Page 7: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Iterators? Say, what? Well, no. I mean, yes.

In the Scheme language and some others, a stream is a lazily evaluated or delayed sequence of data elements. A stream can be used similarly to a list, but later elements are only calculated when needed. Streams can therefore represent infinite sequences and series.

https://en.wikipedia.org/wiki/Stream_(computing)

Page 8: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Srsly. What is a Java 8 Stream?

Source

[IntermediateOperations.]*

TerminalOperation

Page 9: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Streams vs. Collections• No Storage — carry values from a source.

• Functional in nature — do not modify the source.

• Laziness-seeking — efficient short-circuits.

• Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.

• Possibly unbounded — A stream need not be finite, unlike a collection.

• Consumable — one time only.

Page 10: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Streams-relevant Java 8 Review

Page 11: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Functional Interface…• Functional interfaces provide target types for lambda

expressions and method references. Each functional interface has a single abstract method, called the functional method for that functional interface, to which the lambda expression's parameter and return types are matched or adapted.

• The type of the functional interface is inferred from the context and is known as the target type.

Page 12: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

… Functional Interface• @FunctionalInterface

An annotation that indicates an interface type declaration is intended to be a functional interface. (… However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.)

• Functional Interfaces in Java 8 are listed in the package description of java.util.function.

Page 13: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Function Shapes• Function<T, R> (unary function from T to R)

• Consumer<T> (unary function from T to void)

• Predicate<T> (unary function from T to boolean)

• Supplier<R> (nilary function providing R)

• UnaryOperator<T> (a function from T to T)

• BinaryOperator<T, T> (a function from (T,T) to T)

Page 14: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Method ReferenceEasy-to-read Lambda expression for a named method.

For example: someStream.forEach(e -> { System.out.println(e)});

or: someStream.forEach(System.out::println);

someStream.toArray(size -> new T[size]);

or: someStream.toArray(T[]::new);

Page 15: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Optional• A container object which may or may not contain a

non-null value. If a value is present, isPresent() will return true and get() will return the value.

• Additional methods that depend on the presence or absence of a contained value are provided, such as orElse() (return a default value if value not present) and ifPresent() (execute a block of code if the value is present).

Page 16: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Spliterator• An object for traversing and partitioning elements of a

source.

• A spliterator is the parallel analogue of an Iterator; it describes a (possibly infinite) collection of elements, with support for sequentially advancing, bulk traversal, and splitting off some portion of the input into another spliterator which can be processed in parallel. At the lowest level, all streams are driven by a spliterator. (from java.util.streams)

Page 17: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Creating Streams…Must have a Source! Streams have no data of their own:

• Collections (Collection interface) List<T> myList = …; myList.stream()…; myList.parallelStream() …;

• Arrays: T[] myArray = …; Arrays.stream(myArray)… // alternatively … Stream.of(myArray)…

Page 18: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

…Creating Streams…Retrofitted JDK classes:

• BufferedReader.lines() — lines of a file

• Files.lines(Path file) — lines of a file

• Files.list(Path dir) — file paths contained in dir

• Random.ints()

• BitSet.stream()

• Pattern.splitAsStream(java.lang.CharSequence)

• JarFile.stream()

Page 19: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

…Creating Streams…• Individual Values:

T t1; T t2; T t3; Stream.of(t1, t2, t3)…

• Stream.Builder Stream.Builder<String> sb = Stream.builder(); sb.accept(s1); sb.accept(s2); Stream<String> s = sb.build(). …; or Stream<String> s = Stream.<String>builder().add(s1).add(s2).build();

Page 20: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Creating Streams…• String: String myName… // produces an IntStream of code points String.chars()…

• Generator functions: //Infinite unordered Stream Stream.generate(Supplier<T> s) Stream.iterate(T seed, UnaryOperator<T> f)

Page 21: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Now that you have a Stream, what do you do with it?

• Transform

• Aggregate

• Find

• Reduce

Page 22: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

I'm bored. Where's the code?

(from State of the Lambda: Libraries Edition — slightly edited)

[The following] is a fragment from the JDK class, Class (the getEnclosingMethod method), which loops over all declared methods, matching method name, return type, and number and type of parameters. …

Page 23: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

First, the Original Codefor (Method m : enclosingInfo.getEnclosingClass().getDeclaredMethods()){ if (m.getName().equals(enclosingInfo.getName()) ) { Class<?>[] candidateParamClasses = m.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { boolean matches = true; for (int i = 0; i < candidateParamClasses.length; i++) { if (!candidateParamClasses[i].equals(parameterClasses[i])) { matches = false; break; } }

if (matches) { // finally, check return type if (m.getReturnType().equals(returnType)) return m; } } } }

throw new InternalError("Enclosing method not found");

Page 24: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Then, the Streamified codereturn Arrays.stream(enclosingInfo.getEnclosingClass().getDeclaredMethods()) .filter(m -> Objects.equals(m.getName(), enclosingInfo.getName()) .filter(m -> Arrays.equals(m.getParameterTypes(), parameterClasses)) .filter(m -> Objects.equals(m.getReturnType(), returnType)) .findFirst() .orElseThrow(() -> new InternalError("Enclosing method not found");

Page 25: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Intermediate Operations• map

• filter

• limit

• skip

• parallel

• sequential

— documented in java.util.stream.Stream

Page 26: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

map (mapToInt, mapToDouble, flatMap)• Stream<R> map(Function<? super T,? extends R> mapper)

• The mapper function is applied to each element of the stream and returns a Stream consisting of the results.

• Example: Stream<String> shaggyLines = … List<String> trimmedLines = shaggyLines.map(String::trim) .collect(toList);

• Example2: See Grep.java for flatmap

Page 27: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

filter• Stream<T> filter(Predicate<? super T> predicate)

• Returns a stream consisting of the elements of this stream that match the given predicate.

• Example: IntStream.range(1, 100)

.filter( e -> ((e % 5 == 0) || (e % 3 == 0)) ) .mapToObj( e -> { return

(e % 15 == 0) ? "FizzBuzz" : (e % 5 == 0) ? "Buzz" : "Fizz" ; } )

.forEach(System.out::println);

Page 28: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

parallel & sequential• parallel() — returns an equivalent stream that is parallel,

maybe

• sequential() - returns an equivalent stream that is sequential

• Example: IntStream.range(0, 100) .parallel(). …

Page 29: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

limit & skip• limit(long maxSize) — limits a stream to this number of

elements

• skip(long count) — skips over that many elements

• Example: Stream.iterate(2, n -> n + 2) .limit(10) .skip(4) .forEach(System.out::println);

Page 30: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Terminal Operations• forEach

• toArray, toList

• reduce

• collect

• min, max, count, sum

• anyMatch, allMatch, noneMatch

• findFirst, findAny

• iterator, spliterator

Page 31: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

findFirst & findAny• short-circuit operations

• both return an Optional

• Example in Streamified Class code

Page 32: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

collect• The argument to collect() is a Collector, which embodies a recipe for folding

elements into a data structure or summary.

• The following will accumulate strings into an ArrayList: List<String> asList = stringStream.collect(Collectors.toList());

• The following will classify Person objects by city: Map<String, List<Person>> peopleByCity = personStream.collect(Collectors.groupingBy(Person::getCity));

• The following will classify Person objects by state and city, cascading two Collectors together:

Map<String, Map<String, List<Person>>> peopleByStateAndCity = personStream.collect(Collectors.groupingBy(Person::getState, Collectors.groupingBy(Person::getCity)));

Page 33: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

Read these!State of the Lambda

September 2013 http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html

State of the Lambda: Libraries Edition September, 2013

http://cr.openjdk.java.net/~briangoetz/lambda/lambda-libraries-final.html

Package description for java.util.stream Java™ Platform Standard Ed. 8

http://docs.oracle.com/javase/8/docs/api/index.html

Page 34: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

References• Marty Hall's Java 8 Tutorials:

http://www.coreservlets.com/java-8-tutorial/

• Faster parallel processing in Java using Streams and a spliterator, Marko Topolnik, PhD. :

https://www.airpair.com/java/posts/parallel-processing-of-io-based-data-with-java-streams

• Processing Data with Java SE 8 Streams, Part 1,Raoul-Gabriel Urma:

http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html

Page 35: Java 8 Streams - java.ociweb.comjava.ociweb.com/javasig/knowledgebase/2015-01/Java8Streams.pdf · Java 8 Streams Saint Louis Java Users Group 8 January, 2015 Charles A Sharp csharp@ociweb.com

“You can know the name of a bird in all the languages of the world, but when you're finished,

you'll know absolutely nothing whatever about the bird… So let's look at the bird and see what it's doing — that's what counts. I learned very

early the difference between knowing the name of something and knowing something.”

— Richard Feynman