java 8 streams
DESCRIPTION
This is a brief introduction to "Java 8 Streams" featuring: * Bulk Operations * Lambda Expressions * Method References * Functional Operations * Collectors * ... Accompanying source code and examples can be found on https://github.com/bkimminich/java8-streamsTRANSCRIPT
![Page 1: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/1.jpg)
Java 8 Streams
J8S 1.2.1 (10.04.2023)
Björn Kimminich
https://twitter.com/bkimminichhttps://linkedin.com/in/bkimminichhttps://google.com/+BjörnKimminichhttp://slideshare.net/BjrnKimminich/
![Page 2: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/2.jpg)
Agenda
•Java 8•Streams•Lambdas•Method
References
Introduction
•Intermediate vs. Terminal
•Stateless vs. Stateful
•Short-Circuiting
•Collectors
Stream Operations
![Page 3: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/3.jpg)
Java 8
![Page 4: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/4.jpg)
Java™ SE 8 Release Contents
JSR 308: Annotations on Java TypesJSR 310: Date and Time APIJSR 335: Lambda Expressions
closuresJEP 107: Bulk Data Operations for Collections
for-eachfiltermapreduce http://www.jcp.org/en/jsr/detail?id=337
http://openjdk.java.net/jeps/107
![Page 5: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/5.jpg)
Streams
![Page 6: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/6.jpg)
Streams
interface java.util.stream.Stream<T>forEach()filter()map()reduce()…
java.util.Collection<T>Stream<T> stream()Stream<T> parallelStream()
![Page 7: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/7.jpg)
Creating and using a Stream
List<Book> myBooks = …;
Stream<Book> books = myBooks.stream();
Stream<Book> goodBooks =books.filter(b -> b.getStarRating() > 3);
goodBooks.forEach(b -> System.out.println(b.toString()));
![Page 8: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/8.jpg)
Properties of Streams
Streams do not store elements……they are a view on top of a data structure
Operations provided by Streams...…are applied to the underlying data source elements
Stream Operations can take as a parameter…
…Lambda expressions…Method references
Manipulating the underlying data source...
…will yield a ConcurrentModificationException
![Page 9: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/9.jpg)
Lambdas
![Page 10: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/10.jpg)
What are Lambda Expressions?
Java‘s version of ClosuresAllow to create (sort of) First Class Functions
Can be passed as a parameterCan be a return valueCan be stored in a variable
Target type is inferred from context
Why „sort of“?Because Java doesn‘t have a real function type!Java converts Lambdas into Functional Interfaces
![Page 11: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/11.jpg)
Functional Interface
Functional Interface = Interface w/ 1 MethodNames of Interface and Method are irrelevantDefault: java.util.function.Consumer<T>
public interface Stream<T> { void forEach(Consumer<? super T> consumer); } public interface Consumer<T> {void accept(T t);}
Consumer<Book> reduceRankForBadAuthors = (Book b) -> { if (b.getStarRating() < 2) b.getAuthor().addRank(-1); };
books.forEach(reduceRankForBadAuthors);
books.forEach(b -> b.setEstimatedReadingTime(90*b.getPages()));
![Page 12: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/12.jpg)
Lambda Syntax
/* argument list */ (int x, int y) -> { return x*y; } (x, y) -> { return x*y; } x -> { return x*2; }
() -> { System.out.println("Do you think this will work?"); }
/* single expression */ b -> { b.getMissingPages() > threshold ? b.setCondition(BAD)
: b.setCondition(GOOD) }
/* list of statements */ b -> { Condition c = computeCondition(b.getMissingPages()); b.setCondition(c); }
![Page 13: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/13.jpg)
Method References
![Page 14: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/14.jpg)
Method References
books.forEach(b -> b.fixSpellingErrors()); books.forEach(Book::fixSpellingErrors); // instance method
books.forEach(b -> BookStore.generateISBN(b)); books.forEach(BookStore::generateISBN); // static method
books.forEach(b -> System.out.println(b.toString())); books.forEach(System.out::println); // expression
Stream<ISBN> isbns1 = books.map(b -> new ISBN(b)); Stream<ISBN> isbns2 = books.map(ISBN::new); // constructor
![Page 15: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/15.jpg)
Intermediate vs. TerminalStream Operations
![Page 16: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/16.jpg)
Intermediate vs. Terminal
Intermediate: Output is another Stream
filter()map()…
Terminal: Do something else with the Stream
forEach()reduce()…double totalPrice = books.mapToDouble(Book::getPrice)
.reduce(0.0, (p1, p2) -> p1+p2);
![Page 17: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/17.jpg)
Stream Evaluation
Intermediate Streams are not evaluated…
…until a Terminal Operation is invoked on them
Intermediate = LazyTerminal = Eager (Consuming)
This allows Java to……do some code optimization during compilation…avoid buffering intermediate Streams…handle parallel Streams more easily
![Page 18: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/18.jpg)
Terminal = Consuming Operations
books.forEach(b -> System.out.println("Book: " + b.getTitle())); double totalPrice = books.reduce(0.0, (b1, b2)
-> b1.getPrice() + b2.getPrice());
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
Intermediate Operations can be chainedOnly one Terminal Operation can be invokedBest avoid reference variables to Streams entirely by using Fluent Programming
Construction (Intermediate)* Terminal;
![Page 19: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/19.jpg)
Stateless vs. StatefulStream Operations
![Page 20: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/20.jpg)
Stateless Intermediate Operations
Operation need nothing other than the current Stream element to perform its workExamples
map() Maps element to something elsefilter() Apply predicate and keep or drop elementList<Book> myBooks = ...;
double impairments = myBooks.stream().filter(b -> b.getCondition().equals(BAD))
.mapToDouble(Book::getPrice) .reduce(0.0, (p1, p2) -> p1 + p2);
![Page 21: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/21.jpg)
Stateful Intermediate Operations
Operations that require not only the current stream element but also additional state
distinct() Element goes to next stage if it appears the first timesorted() Sort elements into natural ordersorted(Comparator) Sort according to provided Comparatorsubstream(long) Discard elements up to provided offsetsubstream(long, long) Keep only elements in between offsetslimit(long) Discard any elements after the provided max. size
myBooks.stream().map(Book::getAuthor).distinct().forEach(System.out::println);
![Page 22: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/22.jpg)
Short-CircuitingStream Operations
![Page 23: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/23.jpg)
Short-Circuiting Operations
Processing might stop before the last element of the Stream is reached
Intermediatelimit(long)substream(long, long)
TerminalanyMatch(Predicate)allMatch(Predicate)noneMatch(Predicate)findFirst()findAny()
Author rp = new Author("Rosamunde Pilcher");
boolean phew = myBooks.stream() .map(Book::getAuthor) .noneMatch(isEqual(rp));
System.out.println("Am I safe? " + phew);
![Page 24: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/24.jpg)
Collectors
![Page 25: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/25.jpg)
Collectors
<R> R collect(Collector<? super T, A, R> col)
Collect the elements of a Stream into some other data structurePowerful and complex toolCollector is not so easy to implement, but…
…luckily there are lots of factory methods for everyday use in java.util.stream.Collectors
toList()toSet()toCollection(Supplier)toMap(Function, Function)…
![Page 26: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/26.jpg)
Collector Examples
List<Author> authors = myBooks.stream().map(Book::getAuthor)
.collect(Collectors.toList());
double averagePages = myBooks.stream()
.collect(Collectors.averagingInt(Book::getPages));
![Page 27: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/27.jpg)
Joining Collector
Used for concatenation of CharSequencesInternally implemented using StringBuilder
A lot more efficient than a Map-Reduce with intermediately concatenated Strings
// not efficient due to recursive String concatenation. And ugly. String titleList = myBooks.stream().map(Book::getTitle).reduce("", (t1, t2) -> t1+t2);
// Still inefficient. Still ugly (initial line break)titleList = myBooks.stream().map(Book::getTitle).reduce("", (t1, t2) -> t1+"\n"+t2);
// more efficient thanks to StringBuilder. Pretty printed. titleList = myBooks.stream().map(Book::getTitle).collect(Collectors.joining("\n"));
![Page 28: Java 8 Streams](https://reader033.vdocuments.mx/reader033/viewer/2022042507/54b6c71c4a79599f728b45b3/html5/thumbnails/28.jpg)
Thank you…
…for your attention!
All code examples: https://github.com/bkimminich/java8-streams