java.util.stream.*

trzy lata ze Stream API

Krzysztof Chruściel

Diebold-Nixdorf

"A sequence of elements supporting sequential and parallel aggregate operations"

http://downloadclipart.org/do-upload/clipart/2016-08/Cookie_funny_clipart.png

Decorator -------------->

Packing -------------->

Quality -------------->

Decorator -------------->

Packing -------------->

Quality -------------->

GOF

internal iterator pattern

Stream structure

Source

Intermediate operations - pipeline

Terminal operation - return value or side effect


				Stream.of(cookies)
					.filter(Decorator::isDecorated)
					.filter(Packer::isPacked)
					.filter(QualityAssurance::isQualityFulfilled)
					.collect(toList())
					

Source

Factories: Stream.of(), IntStream.range()

Collections: Collection.stream(), Collection.parallelStream()

Arrays: Arrays.stream()

Random: Random.ints()

Files: Files.walk()

more...

Intermediate operations

stateful vs stateless

filter-map-reduce

filter(Predicate<? super T> predicate)

map(Function<? super T,? extends R> mapper)

reduce(T identity, BinaryOperator<T> accumulator)

more...

Terminal operations

Performance

Collectors.toList()

Collectors.toMap(key, value)

Stream.findFirst()

more...

Stream lifecycle

Creation - source

Configuration - pipeline

Execution - terminal

Cleanup - used once

Migration?

The Silence of the Lambdas

1930s

1960s

In most programming languages

Finally in Java

Lazy Evaluation

Side effect


					List<Integer> results = new ArrayList<>();
					IntStream.range(0, 150)
							 .parallel()
							 .filter(s -> s % 2 == 0)
							 .forEach(s -> results.add(s));
					System.out.println(results);
					

Side effect

Type inference


					List<Cookie> cookies = ...
					

					.filter((Cookie cookie) -> cookie.getSize() > 5)
					

					.filter(cookie -> cookie.getSize() > 5)
					

Fully statically typed

Capture variable

Effectively Final


					int factory = 10;
					IntStream.range(1, 5)
						.forEach(number -> this.log(number * factory));
					

					int factory = 10;
					IntStream.range(1, 5)
						.forEach(number -> this.log(number * factory++));
					

variable should be final or effectively final

@FunctionlInterface

Is an Interface

Must have only one abstract method

Compiler check for @

Static methods

Default methods

Demo

Need for Speed

As always, it depends...

Not a magic bullet

Java 9 and streams

takeWhile/dropWhile

Java 8


					Stream.iterate("", s -> s + "s")
							.filter(s->s.length() < 10)
							.forEach(this::log);
					

Java 9


					Stream.iterate("", s -> s + "s")
							.takeWhile(s->s.length() < 10)
							.forEach(this::log);
					

Stream iterate

Java 8


					Stream.iterate(0, i -> i + 1)
					  .limit(10);
					  .forEach(this::log);
					

Java 9


					Stream.iterate(0, i -> i < 10, i -> i + 1)
					  .forEach(this::log);
					

Stream of Nullable

Java 8


					collection.stream()
					  .flatMap(element -> {
						  Integer temp = map.get(element);
						  return temp != null ? Stream.of(temp) : Stream.empty();
					  })
					  .collect(toList());
					

Java 9


					collection.stream()
					  .flatMap(elements -> Stream.ofNullable(map.get(element)))
					  .collect(toList());
					

More

Venkat Subramaniam

Thanks

Krzysztof Chruściel

codecouple.pl

krzysztof.chrusciel@outlook.com

github.com/kchrusciel/sjug-streams