Slide 1

Slide 1 text

Collection Builders and Quantifiers vs Streams Michael Wiedeking ([email protected]) 4th Virtual Machine Meetup – Prague 29. September 2017

Slide 2

Slide 2 text

Motivation

Slide 3

Slide 3 text

In Java, what are the advantages of streams over loops?

Slide 4

Slide 4 text

Streams … have a more declarative style … are often terser … have a strong affinity with functions … encourage less mutability … encourage looser coupling … can succinctly express quite sophisticated behaviour … provide scope for future efficiency gains But: – Performance – Familiarity – Cognitive overhead – Debugging https://stackoverflow.com/questions/44180101/in-java-what-are-the-advantages-of-streams-over-loops#44180875

Slide 5

Slide 5 text

return students.stream() .filter(s –> s.age() < 18) .collect(toList()) ;

Slide 6

Slide 6 text

List filtered = new ArrayList<>(); for (Student s : students) { if (s.age() < 18) { filtered.add(s); } } return filtered;

Slide 7

Slide 7 text

return ⟨s ∈ students ∣ s.age < 18⟩

Slide 8

Slide 8 text

return ⟨s ∣ s ∈ students, s.age < 18⟩

Slide 9

Slide 9 text

students.stream() .filter(x –> x.age() < 18) .findFirst() ;

Slide 10

Slide 10 text

students.stream() .filter(x –> x.age() < 18) .findFirst() ; students.stream() .filter(x –> x.age() < 18) .limit(1) ;

Slide 11

Slide 11 text

List a = Arrays.asList(3, 1, 7, 4, 2, 5, 9, 8, 6); Stream s = a.stream() .filter(x –> x < 5) .sorted() ; System.out.println(s.limit(3).collect(Collectors.toList())); System.out.println(s.count());

Slide 12

Slide 12 text

List a = Arrays.asList(3, 1, 7, 4, 2, 5, 9, 8, 6); Stream s = a.stream() .filter(x –> x < 5) .sorted() ; System.out.println(s.limit(3).collect(Collectors.toList())); System.out.println(s.count()); [1, 2, 3] Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed

Slide 13

Slide 13 text

Point of View

Slide 14

Slide 14 text

s.stream().foreach(f);

Slide 15

Slide 15 text

s.stream().foreach(f); for x ∈ s do f(x) end

Slide 16

Slide 16 text

sum = 0; s.stream() .foreach(x –> sum += x) ; println(sum); sum ← 0 for x ∈ s do sum ← sum + x end printLine(sum)

Slide 17

Slide 17 text

sum = 0; s.stream() .foreach(x –> sum += x) ; println(sum); sum ← 0 for x ∈ s do sum ← sum + x end printLine(sum)

Slide 18

Slide 18 text

a = new int[1]; s.stream() .foreach(x –> a[0] += x) ; println(a[0]); sum ← 0 for x ∈ s do sum ← sum + x end printLine(sum)

Slide 19

Slide 19 text

a = new int[1]; s.stream() .filter(x >= 0) .foreach(x –> a[0] += x) ; println(a[0]); sum ← 0 for x ∈ s, x ≥ 0 do sum ← sum + x end printLine(sum)

Slide 20

Slide 20 text

sum ← 0 for x ∈ s do sum ← sum + x if sum ≥ limit then break end end printLine(sum)

Slide 21

Slide 21 text

Collection Builders

Slide 22

Slide 22 text

● List.of(…) ● Set.of(…) ● Map.of(k 1 , v 1 , … , k 10 , v 10 ) ● Map.ofEntries(entry(k 1 , v 1 ), … , entry(k 10 , v 10 ), …)

Slide 23

Slide 23 text

(1, 2, 2, 3) {1, 2, 3} {1 ↦ ‘a’, 2 ↦ ‘b’, 3 ↦ ‘c’} ⦃1, 2, 2, 3⦄ ⟨1, 2, 2, 3⟩ [1, 2, 2, 3] [1 2 3] [1 2; 3 4] Tuple Set Map Bag List Array Vector Matrix

Slide 24

Slide 24 text

● {1, … , n} ● {1, 3, … , n} ● {a, a + Δ, … , b} ● {a, a − Δ, … , b} ● {a, …} ● {a, a + Δ, … } ● {…, −1, 0, +1, …} ● {a, b, c, d, e, f, g} ● {1, 2, 3, 4, 5, 6, 7} ● {1, … , 5; 7, 8; 10, … , 15; 20, … , 25; 30, 31}

Slide 25

Slide 25 text

x_class := [ CA FE BA BE 00 00 00 35 00 05 07 00 03 07 00 04 01 00 01 58 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 06 01 00 01 00 02 00 00 00 00 00 00 00 00 ] 16 x_class : Array⟦ 1 ⟧ = [ (CA) 16 , (FE) 16 , (BA) 16 , (BE) 16 , … ]

Slide 26

Slide 26 text

{(x 1 , x 2 , … , x n ) | x 1 ∈ C 1 , p 1 (x 1 ); x 2 ∈ C 2 (x 1 ), p 2 (x 1 , x 2 ); … ; x n–1 ∈ C n–1 (x 1 , x 2 , … , x n–2 ), p n–1 (x 1 , x 2 , … , x n–1 ); x n ∈ C n (x 1 , x 2 , … , x n ), p n (x 1 , x 2 , … , x n ) }

Slide 27

Slide 27 text

{(x, y, z) ∣ x ∈ S, y ∈ S, z ∈ S, x² + y² = z²} where S := {1, … , N}

Slide 28

Slide 28 text

{(x, y, z) ∣ x ∈ S, y ∈ S, z ∈ S, x² + y² = z²} where S := {1, … , N} ⟨(x, y, z) ∣ x ∈ {1, … , N}, y ∈ {x, … , N}, z ∈ {y, … , N}, x² + y² = z² ⟩

Slide 29

Slide 29 text

{(x, y, z) ∣ x ∈ S, y ∈ S, z ∈ S, x² + y² = z²} where S := {1, … , N} ⟨(x, y, z) ∣ x ∈ {1, … , N}, y ∈ {x, … , N}, z ∈ {y, … , N}, x + y ≤ z, x² + y² = z² ⟩

Slide 30

Slide 30 text

C 1 := {1, 2, 3} C 2 := {2, 3, 4} assert {x | x ∈ C 1 ∧ x ∈ C 2 } = {2, 3} assert {x | x ∈ C 1, x ∈ C 2 } = {2, 3} assert {x | x ∈ C 1, y ∈ C 2 } = {1, 2, 3} assert {(x, y) | x ∈ C 1, y ∈ C 2 } = {(1, 2), (1, 3), (1, 4), (2, 2), …} assert {x | x ∈ C 1 ∨ x ∈ C 2 } = {1, 2, 3, 4} assert ⟨x | x ∈ C 1 ∨ x ∈ C 2 ⟩ = ⟨1, 2, 3, 2, 3, 4⟩ assert ⟨x | x ∈ C 1 ∘ C 2 ⟩ = ⟨1, 2, 3, 2, 3, 4⟩ assert ⟨x | x ∈ C 1 ‡ C 2 ⟩ = ⟨1, 2, 2, 3, 3, 4⟩

Slide 31

Slide 31 text

s.map(t) {t(x) | x ∈ s}

Slide 32

Slide 32 text

assert {x² | x ∈ {1, … , 5}} = {1, 4, 9, 16, 25}

Slide 33

Slide 33 text

Quantifiers

Slide 34

Slide 34 text

… s.stream().allMatch(p) … s.stream().anyMatch(p) … s.stream().noneMatch(p)

Slide 35

Slide 35 text

… s.stream().allMatch(p) … s.stream().anyMatch(p) … s.stream().noneMatch(p) … ∀(x ∈ s) p(x) … ∃(x ∈ s) p(x) … ∄(x ∈ s) p(x)

Slide 36

Slide 36 text

o = s.filter(p).findAny(); if (o.isPresent()) { (o.get()); } if ∃(x ∈ s) p(x) then (x) end

Slide 37

Slide 37 text

Everything else

Slide 38

Slide 38 text

● s.count() ● s.findAny() ● s.findFirst() ● s.min(c) ● s.max(c) ● s.skip(n) ● s.dropWhile(p) ● s.takeWhile(p) ● s.reduce(…) ● s.collect(…) ● s.limit(n)

Slide 39

Slide 39 text

s.findAny() s.findFirst() s.count() arb s s.arb() s.first() |s| s.numberOfElements()

Slide 40

Slide 40 text

{1, 2, 3} ⦃1, 2, 2, 3⦄ ⟨1, 2, 2, 3⟩ [1, 2, 2, 3] ● ordered skip(n) dropWhile(p) takeWhile(p) ● others ⟪⟫❨❩❲❳⁅ ⁆⸦⸧⦅⦆⦇⦈⦉⦊⦋ ⦌⦍ ⦎⦏ ⦐⦑⦒⦓⦔⦕⦖⸢⸣⸤⸥⸨⸩⟬⟭⟮⟯⌈⌉⌊⌋ unordered, unique unordered ordered ordered

Slide 41

Slide 41 text

∑[1 ≤ k ≤ n] 2k ∑{k | k ∈ {1, … , n}} 2k ∑⟨(i, j) | i ∈ ⟨1, … , n⟩, j ∈ ⟨1, … , m⟩⟩ a[i][j]

Slide 42

Slide 42 text

Examples

Slide 43

Slide 43 text

Pythagorean Quadruples a² + b² + c² = d²

Slide 44

Slide 44 text

S := {1, … , N} S ∖ {d ∣ a ∈ S, b ∈ S, c ∈ S, d ∈ S, a² + b² + c² = d²}

Slide 45

Slide 45 text

S := {1, … , N} S ∖ {d ∣ a ∈ S, b ∈ S, c ∈ S, d ∈ S, a² + b² + c² = d²} {d ∣ d ∈ S, ∄(a ∈ S) ∄(b ∈ S) ∄(c ∈ S) a² + b² + c² = d²}

Slide 46

Slide 46 text

S := {1, … , N} S ∖ {d ∣ a ∈ S, b ∈ S, c ∈ S, d ∈ S, a² + b² + c² = d²} {d ∣ d ∈ S, ∄(a ∈ S) ∄(b ∈ S) ∄(c ∈ S) a² + b² + c² = d²} {d ∣ d ∈ S, ∀(a ∈ S) ∀(b ∈ S) ∀(c ∈ S) a² + b² + c² ≠ d²}

Slide 47

Slide 47 text

S := {1, … , N} S ∖ {d ∣ a ∈ S, b ∈ S, c ∈ S, d ∈ S, a² + b² + c² = d²} {d ∣ d ∈ S, ∄(a ∈ S) ∄(b ∈ S) ∄(c ∈ S) a² + b² + c² = d²} {d ∣ d ∈ S, ∀(a ∈ S) ∀(b ∈ S) ∀(c ∈ S) a² + b² + c² ≠ d²} {d ∈ S ∣ ∀(a ∈ S) ∀(b ∈ S) ∀(c ∈ S) a² + b² + c² ≠ d²}

Slide 48

Slide 48 text

100 % println( IntStream.rangeClosed(1, N).filter(d –> IntStream.range(1, d).allMatch(a –> IntStream.range(a, d).allMatch(b –> IntStream.range(b, d).allMatch(c –> a * a + b * b + c * c != d * d; ) ) ) ) .collect(toList()) );

Slide 49

Slide 49 text

100 % println( IntStream.rangeClosed(1, N).filter(d –> { return IntStream.range(1, d).allMatch(a –> { return IntStream.range(a, d).allMatch(b –> { return IntStream.range(b, d).allMatch(c –> { return a * a + b * b + c * c != d * d; }); }); }); }) .collect(toList()) );

Slide 50

Slide 50 text

~70 % println( IntStream.rangeClosed(1, N).filter(d –> { int dd = d * d; return IntStream.range(1, d).allMatch(a –> { int aa = a * a; return IntStream.range(a, d).allMatch(b –> { int aa_bb = aa + b * b; return IntStream.range(b, d).allMatch(c –> { return aa_bb + c * c != dd; }); }); }); }) .collect(toList()) );

Slide 51

Slide 51 text

{d ∈ S ∣ ∀(a ∈ S) ∀(b ∈ S) ∀(c ∈ S) a² + b² + c² ≠ d²} where S := {1, … , N}

Slide 52

Slide 52 text

~7 % {d ∈ {1, … , N} ∣ ∀(a ∈ {1, … , d}) ∀(b ∈ {a, … , d}) ∀(c ∈ {b, … , d}) a² + b² + c² ≠ d² }

Slide 53

Slide 53 text

~6 % {d ∈ {1, … , N} ∣ ∀(a ∈ {1, … , d} where dd := d²) ∀(b ∈ {a, … , d} where aa := a²) ∀(c ∈ {b, … , d} where aa_bb := aa + b²) aa_bb + c² ≠ dd }

Slide 54

Slide 54 text

Poker

Slide 55

Slide 55 text

public static boolean isFlush(Hand hand) { return hand.stream() .allMatch( c –> hand.stream() .filter(cc –> cc != c) .allMatch(cc –> cc.suit == c.suit) ) ; }

Slide 56

Slide 56 text

public static boolean isFlush(Hand hand) { Card arb = hand.stream().findAny().get(); return hand.stream() .filter(c –> c != arb) .allMatch(c –> c.suit == arb.suit) ; }

Slide 57

Slide 57 text

public static boolean isFlush(Hand hand) { Card arb = hand.stream().findAny().get(); Suit suit = arb.suit; return hand.stream() .filter(c –> c != arb) .allMatch(c –> c.suit == suit) ; }

Slide 58

Slide 58 text

function isFlush(Hand hand) → is return ∀(c ∈ hand) ∀(cc ∈ hand, cc ≠ c) ( cc.suit = c.suit ) end

Slide 59

Slide 59 text

function isFlush(Hand hand) → is return ( ∀(cc ∈ hand where c := arb(hand), cc ≠ c) cc.suit = c.suit ) end

Slide 60

Slide 60 text

function isFlush(Hand hand) → is return ( ∀( cc ∈ hand where (c := arb(hand); suit := c.suit), cc ≠ c ) cc.suit = suit ) end

Slide 61

Slide 61 text

function isFlush(Hand hand) → is return ( ∀( cc ∈ hand where c := arb(hand), suit := c.suit, cc ≠ c ) cc.suit = suit ) end

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

function fourOfAKind(Hand hand) → is return ( ∃(s ∈ ℘₄(hand)) ∀(c ∈ s where r := arb(s).rank) (c.rank = r) ) end

Slide 64

Slide 64 text

Quintessence

Slide 65

Slide 65 text

∃(x ∈ s) (∃x ∈ s)

Slide 66

Slide 66 text

Questions?

Slide 67

Slide 67 text

Thank You! For more information about quantifiers in Aalgola see aalgola.org