Scala Collections : Java 8 on Steroids
-
Upload
huitseeker -
Category
Science
-
view
332 -
download
1
description
Transcript of Scala Collections : Java 8 on Steroids
What this talk is
2
What this talk is
! A look at Java 8 gives you
2-a
What this talk is
! A look at Java 8 gives you
! ... and what it doesn’t
2-b
What this talk is
! A look at Java 8 gives you
! ... and what it doesn’t
! A look at Scala collections
2-c
What this talk is
! A look at Java 8 gives you
! ... and what it doesn’t
! A look at Scala collections
! A look at the why and how of collections
2-d
What this talk is not
3
What this talk is not
! New stuff
3-a
What this talk is not
! New stuff
! Rocket Science
3-b
What this talk is not
! New stuff
! Rocket Science
! Polemic
3-c
What I’m hoping for
4
What I’m hoping for
! A discussion
4-a
What I’m hoping for
! A discussion
! Making things a tad more clear
4-b
What I’m hoping for
! A discussion
! Making things a tad more clear
! ... or just less overlooked ?
4-c
What I’m hoping for
! A discussion
! Making things a tad more clear
! ... or just less overlooked ?
! Not too boring
4-d
What (functional, new things) you can do with Java 8
Lambda-expressions
(String first, String second) ->
Integer.compare(first.length(), second.length)
Functional Interfaces
Runnable r = () -> System.out.println("I am Runnable!");
Method references
button.setOnAction(System.out::println);
Constructor references
List<String> labels = ... ;
Stream<Button> buttonsStream = labels.stream().map(Button::new);
Buttons[] buttonsArray = labels.stream().toArray(Button::new);
int[]::new;
5
The devil is in the details
Optional<T>, Optional.of(), Optional.ofNullable(), Optional.empty()
Default methods in interfaces.
list.forEach(System.out::println)
... beware: SuperClasses win, Interfaces clash. ... And the standard library was not
entirely rewritten (Path/Paths)
Important topics : variable capture in closures, parallel execution.
int[] counter = new int[1];
button.setOnAction(event -> counter[0]++);
6
And also, Streams
! Any Collection has a stream()
! Stream.of() with a vararg, an array
! filter, map, flatMap, as well as plumbing: split, concat, limit
! Lazy processing, parallel() processing (you enforce statelessness)
! terminal reductions, e.g. reduce
! collector:HashSet<String> result =
stream.collect(HashSet::new, HashSet::add, HashSet::addAll)
! Collector implementations (toList, toMap, ...)
! counting, maxBy, groupinBy, mapping, ...
! Beware: think about reuse.
7
Interlude
8
Interlude
! Does that make Java a functional programming language ?
8-a
Interlude
! Does that make Java a functional programming language ?
! First class functions
8-b
Interlude
! Does that make Java a functional programming language ?
! First class functions
! Technicalities
8-c
Interlude
! Does that make Java a functional programming language ?
! First class functions
! Technicalities
! Does that make Java a Scala competitor ?
8-d
Interlude
! Does that make Java a functional programming language ?
! First class functions
! Technicalities
! Does that make Java a Scala competitor ?
! Scala has never had a feature poverty problem.
8-e
What you can’t do with Java 8 (yet)
1. Case classes
2. Pattern matching
3. Tail call elimination
4. Scoped access
5. Lazy keyword
6. Traits (well-scoped)
7. Rich Imports (local, aliased)
8. Macros
9. Backend (Miguel Garcia)
10. Specialization (Vlad Ureche)
11. Value classes
12. Implicits
13. Cake !
9
Collections
! The signatures of map
! Type classes & implicits
! Design goals
10
The signatures of map
11
The signatures of map
! def map[B](f: (A) ⇒ B) : Map[B]
11-a
The signatures of map
! def map[B](f: (A) ⇒ B) : Map[B]
! But ... Type Constructor Polymorphism
11-b
The signatures of map
! def map[B](f: (A) ⇒ B) : Map[B]
! But ... Type Constructor Polymorphismtrait TraversableLike[+Elem, +Coll[+x]] {
def map[NewElem](f: Elem ⇒ NewElem): Coll[NewElem]
def filter(p: Elem ⇒ Boolean): Coll[Elem]
}
11-c
The signatures of map
! def map[B](f: (A) ⇒ B) : Map[B]
! But ... Type Constructor Polymorphismtrait TraversableLike[+Elem, +Coll[+x]] {
def map[NewElem](f: Elem ⇒ NewElem): Coll[NewElem]
def filter(p: Elem ⇒ Boolean): Coll[Elem]
}
! The idea that, whatever map needs, it will always deal with:
11-d
The signatures of map
! def map[B](f: (A) ⇒ B) : Map[B]
! But ... Type Constructor Polymorphismtrait TraversableLike[+Elem, +Coll[+x]] {
def map[NewElem](f: Elem ⇒ NewElem): Coll[NewElem]
def filter(p: Elem ⇒ Boolean): Coll[Elem]
}
! The idea that, whatever map needs, it will always deal with:(Collection[Elements],
Elements ⇒ OtherElements,
Collection[OtherElements])
11-e
The signatures of map
12
The signatures of map
12-a
The signatures of map
! trait TraversableLike[+Elem, +Repr] {
protected[this] def newBuilder: Builder[Elem, Repr] // deferred
def foreach[U](f: Elem ⇒ U) // deferred
def filter(p: Elem ⇒ Boolean): Repr = {
val b = newBuilder
foreach { elem <- if (p(elem)) b += elem }
b.result
}
}
class Builder[-Elem, +To] {
def +=(elem: Elem): this.type = . . .
def result(): To = . . .
def clear() = . . .
def mapResult[NewTo](f: To ⇒ NewTo): Builder[Elem, NewTo] = . . .
}
12-b
The signatures of map
! trait TraversableLike[+Elem, +Repr] {
protected[this] def newBuilder: Builder[Elem, Repr] // deferred
def foreach[U](f: Elem ⇒ U) // deferred
def filter(p: Elem ⇒ Boolean): Repr = {
val b = newBuilder
foreach { elem <- if (p(elem)) b += elem }
b.result
}
}
class Builder[-Elem, +To] {
def +=(elem: Elem): this.type = . . .
def result(): To = . . .
def clear() = . . .
def mapResult[NewTo](f: To ⇒ NewTo): Builder[Elem, NewTo] = . . .
}
! Why do we care ? Extensibility.
12-c
The signatures of map (cont’d)
13
The signatures of map (cont’d)
13-a
The signatures of map (cont’d)
! def map[B, That](f: ((A,B)) ⇒ B)
(implicit bf:CanBuildFrom[Map[A,B], B, That]):That
13-b
The signatures of map (cont’d)
! def map[B, That](f: ((A,B)) ⇒ B)
(implicit bf:CanBuildFrom[Map[A,B], B, That]):That
! Why ?
13-c
The signatures of map (cont’d)
! def map[B, That](f: ((A,B)) ⇒ B)
(implicit bf:CanBuildFrom[Map[A,B], B, That]):That
! Why ?
! Dealing with (Bitset, Int, BitSet) and
(Bitset, String, Set[String])
13-d
The signatures of map (cont’d)
! def map[B, That](f: ((A,B)) ⇒ B)
(implicit bf:CanBuildFrom[Map[A,B], B, That]):That
! Why ?
! Dealing with (Bitset, Int, BitSet) and
(Bitset, String, Set[String])
! Dealing with (Map[A, B], (A, B)) ⇒ (B, A), Map[B, A]) and
(Map[A, B], (A, B)) ⇒ T, Iterable[T])
13-e
With Implicits
trait CanBuildFrom[-Collection, -NewElem, +Result] {
def apply(from: Collection): Builder[NewElem, Result]
}
trait TraversableLike[+A, +Repr] {
def repr: Repr = . . .
def foreach[U](f: A ⇒ U): Unit = . . .
def map[B, To](f: A ⇒ B)(implicit cbf: CanBuildFrom[Repr, B, To]): To = {
val b = cbf(repr) // get the builder from the CanBuildFrom instance
for (x <- this) b += f(x) // transform element and add
b.result
}
}
14
trait SetLike[+A, +Repr] extends TraversableLike[A, Repr] { }
trait BitSetLike[+This <: BitSetLike[This] with Set[Int]]
extends SetLike[Int, This] {}
trait Traversable[+A] extends TraversableLike[A, Traversable[A]]
trait Set[+A] extends Traversable[A] with SetLike[A, Set[A]]
class BitSet extends Set[Int] with BitSetLike[BitSet]
object Set {
implicit def canBuildFromSet[B] = new CanBuildFrom[Set[_], B, Set[B]] {
def apply(from: Set[_]) = . . .
}
}
object BitSet {
implicit val canBuildFromBitSet = new CanBuildFrom[BitSet, Int, BitSet] {
def apply(from: BitSet) = . . .
}
}
15
ConclusionA word about design.
16