Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scala for Java Programmers (Short Edition)

Scala for Java Programmers (Short Edition)

JavaプログラマのためのScala入門 (Short Edition) v1.1

目次:
- Scala とは?
- case クラス
- パターンマッチ
- コレクション
-- コレクション演算
-- 不変コレクション
-- 並列コレクション
- Option 型

Yuta Okamoto

March 10, 2013
Tweet

More Decks by Yuta Okamoto

Other Decks in Technology

Transcript

  1. Short Edition? • ౰ॳ͸ɺJava ಉ౳ͷػೳ → Scala ಛ༗ͷػೳ·ͰΛ ࡾষߏ੒Ͱ঺հ͍ͯ͘͠༧ఆͩͬͨɻ •

    …͕ɺҰষͷ࣌఺Ͱϖʔδ਺͕ੌ͍ࣄʹͳΓஅ೦ɻ • ࠓճ͸ɺ໌೔࢖͑ΔศརػೳΛηϨΫτͯ͠͝঺հɻ
  2. Scalaͱ͸ʁ • Java VM ্Ͱಈ࡞͢Δϓϩάϥϛϯάݴޠɻ • 2003 ೥ʹ࠷ॳͷόʔδϣϯ͕ϦϦʔε͞Εͨɻ • ࠷৽൛͸

    2.10ʢ2013 ೥ 3 ݄ݱࡏʣɻ • εΠε࿈๜޻Պେֶϩʔβϯψߍͷ Martin Odersky ڭत͕։ൃɻ • Java 5 ͷ Generics ΍ݱߦੈ୅ͷ javac ͷ։ൃʹܞΘͬͨਓ෺ɻ • 2011 ೥ʹ Scala ͷαϙʔτ΍ίϯαϧΛߦ͏ Typesafe ࣾΛઃཱɻ
  3. Scalaͷಛ௃ - 2 • εέʔϥϒϧͳݴޠ (SCAlable LAnguage) • খ͞ͳεΫϦϓτ͔Βେ͖ͳγεςϜ·Ͱهड़Մɻ •

    υϝΠϯಛԽݴޠ (DSL) Λߏங͢ΔͨΊͷ༷ʑͳػ ೳ͕αϙʔτ͞Ε͍ͯΔɻ
  4. $ scala Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit

    Server VM, Java 1.6.0_37). Type in expressions to have them evaluated. Type :help for more information. scala> 1 + 2 res0: Int = 3 scala> println("1 + 2 = " + res0) 1 + 2 = 3 scala> :quit
  5. public class Person { private String name = null; private

    int age = 0; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } } Java Person - name: String - age: int case Ϋϥε
  6. class Person(var name: String, var age: Int) Person - name:

    String - age: int Scala ͨͬͨҰߦʂ ˍ Ϋϥεͷҙਤ͕໌֬ʂ var/val Λ͚ͭΔ case Ϋϥε
  7. class Person(var name: String, var age: Int) Scala class Person(name:

    String, age: Int) { def name: String = name def name_=(name: String) { this.name = name } def age: Int = age def age_=(age: Int) { this.age = age } } getter setter ίϯετϥΫλ ʹ ΞΫηα͕ࣗಈతʹఆٛ͞ΕΔ ʢຊ౰ͷ Scala ίʔυͰ͸ͳ͍͚Ͳɺงғؾ͸͜Μͳײ͡ͱ͍͏͜ͱͰʣ case Ϋϥε
  8. val p = new Person(“Tom Green”, 25) println(“age: ” +

    p.age) // p.age() p.name = “Martin Odersky” // p.name_=(“Martin Odersky”) Scala ϑΟʔϧυͱಉ͡จ๏Ͱ ࢀরɾߋ৽Ͱ͖Δ ʢ࣮ࡍͷॲཧ͸ getter/setter Λܦ༝͢ΔͷͰ ΧϓηϧԽ͕कΒΕΔʣ case Ϋϥε
  9. public class Person { private String name = null; private

    int age = 0; ... public boolean equals(Object obj) { if (obj == null) return false; if (obj instanceof Person) { Person rhs = (Person) obj; if (this.name == null) return rhs.name == null; return this.name.equals(rhs.name) && this.age == rhs.age; } return super.equals(obj); } public int hashCode() { return 31 * this.name.hashCode() + this.age; } public String toString() { return “Person(” + this.name + “,” + this.age + “)”; } } Java case Ϋϥε ਖ਼࣮͘͠૷͢Δͷ͸େม…
  10. case class Person(var name: String, var age: Int) val p1

    = Person(“Tom Green”, 25) val p2 = Person(“Martin Odersky”, 54) p1.equals(p2) hashSet.add(p1) // depends on hashCode() println(p1.toString()) // “Person(Tom Green,25)” Scala શͯࣗಈతʹ࣮૷͞ΕΔ case Ϋϥε
  11. ·ͱΊ • Scala ʹ͸σʔλΫϥε༻ͷ౶ҥߏจ͕͋Δɻ • ίϯετϥΫλ΍ getter/setter Λࣗಈతʹఆٛ͢Δ ౶ҥߏจɻ •

    equals() ౳Λࣗಈతʹ࣮૷͢Δ case Ϋϥεɻ • case Ϋϥεͷ͝རӹ͸ଞʹ΋ɻৄ͘͠͸ޙ΄Ͳ… case Ϋϥε
  12. switch (ch) { case ‘ ’: buf.append(‘-’); break; case ‘¥n’:

    buf.append(‘:’); break; default: buf.append(ch); break; } Java •Java ͷ switch จͷෆศͳͱ͜Ζ •੔਺஋ͱจࣈྻ͔͠ൺֱͰ͖ͳ͍ɻ •ൺֱΞϧΰϦζϜ͕”Ұக”͔͠࢖͑ͳ͍ɻ ύλʔϯϚον
  13. ch match { case ‘ ‘ => buf.append(‘-’) case ‘¥n’

    => buf.append(‘:’) case _ => buf.append(ch) } Scala switch (ch) { case ‘ ’: buf.append(‘-’); break; case ‘¥n’: buf.append(‘:’); break; default: buf.append(ch); break; } Java ߏจ͸ࣅ͍ͯΔ •switch ͷ୅ΘΓʹ match Λ࢖͏ɻ •۠੾Γه߸͸ => Λ࢖͏ɻ •ϑΥʔϧεϧʔ͸͠ͳ͍ɻ break จ͸ෆཁ ύλʔϯϚον
  14. abstract class Tree case object Empty extends Tree case class

    Node( elem: Int, left: Tree, right: Tree) extends Tree Tree Empty - elem: Int - left: Tree - right: Tree ྫ: ೋ෼໦ Node ύλʔϯϚον
  15. abstract class Tree case object Empty extends Tree case class

    Node( elem: Int, left: Tree, right: Tree) extends Tree def traverse(t: Tree) = t match { case empty: Empty => Nil case node: Node => traverse(node.left) ::: List(node.elem) ::: traverse(node.right) } Scala ύλʔϯϚον ஋ͷܕΛൺֱͰ͖Δ Node ͔Βதͷ஋ΛऔΓग़͢ࡍʹɺ Tree ͔Β Node ΁ͷΩϟετ͕ෆཁͳ͜ͱʹ஫໨ʂ
  16. abstract class Tree case object Empty extends Tree case class

    Node(elem: Int, left: Tree, right: Tree) extends Tree def traverse(t: Tree) = t match { case Empty => Nil case Node(e, l, r) => traverse(l) ::: List(e) ::: traverse(r) } Scala ύλʔϯϚον த਎Λநग़Ͱ͖Δʂ ஋ͷநग़͸ case Ϋϥεͷػೳͷͻͱͭ ίϯετϥΫλͱಉ͡ه๏ʂ
  17. ೖΕࢠʹͳ͍ͬͯͯ΋ ෼ղͰ͖Δ t match { case Node(e1, Node(e2, Empty, Empty),

    Node(e3, Empty, Empty)) => ... case ... } Scala ύλʔϯϚον e1 e2 E e3 E E E
  18. case class Person(name: String, age: Int) def isAdult(p: Person) =

    p match { case Person(“Martin Odersky”, _) => true case Person(_, age) if (age >= 18) => true case _ => false } Scala ύλʔϯϚον ෳࡶͳ৚݅෼ذ΋ ؆ܿʹهड़Ͱ͖Δ ໊લ͕ Ұக ͨ͠Β true 18 ࡀ Ҏ্ ͳΒ true _ ͸ϫΠϧυΧʔυ
  19. class CarElementPrintVisitor implements CarElementVisitor { public void visit(Wheel wheel) {

    System.out.println("Visiting " + wheel.getName() + " wheel"); } public void visit(Engine engine) { System.out.println("Visiting engine"); } public void visit(Body body) { System.out.println("Visiting body"); } public void visit(Car car) { System.out.println("Visiting car"); } } class CarElementDoVisitor implements CarElementVisitor { public void visit(Wheel wheel) { System.out.println( "Kicking my " + wheel.getName() + " wheel"); } public void visit(Engine engine) { System.out.println("Starting my engine"); } public void visit(Body body) { System.out.println("Moving my body"); } public void visit(Car car) { System.out.println("Starting my car"); } } ύλʔϯϚον from http://en.wikipedia.org/wiki/Visitor_pattern ͳʹ͜Ε͜Θ͍ (ʀʉʔʉ) interface CarElementVisitor { void visit(Wheel wheel); void visit(Engine engine); void visit(Body body); void visit(Car car); } interface CarElement { void accept(CarElementVisitor visitor); } class Wheel implements CarElement { private String name; public Wheel(String name) { this.name = name; } public String getName() { return this.name; } public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Engine implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Body implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Car implements CarElement { CarElement[] elements; public Car() { ... } public void accept(CarElementVisitor visitor) { for(CarElement elem : elements) { elem.accept(visitor); } visitor.visit(this); } } Java
  20. abstract class CarElement case class Wheel(name: String) extends CarElement case

    object Engine extends CarElement case object Body extends CarElement case class Car(elements: List[CarElement]) extends CarElement def print(elem: CarElement) = elem match { case Wheel(name) => println(“Visiting” + name + “ wheel”) case Engine => println(“Visiting engine”) case Body => println(“Visiting body”) case Car(elements) => elements foreach print; println(“Visiting car”) } def doSomething(elem: CarElement) = elem match { case Wheel(name) => println(“Kicking my ” + name + “ wheel”) case Engine => println(“Starting my engine”) case Body => println(“Moving my body”) case Car(elements) => elements foreach doSomething; println(“Starting my car”) } Scala ύλʔϯϚον
  21. public String func(List<Person> persons) { List<Person> filtered = new ArrayList<Person>();

    for (Person p : persons) { if (p.getAge() >= 18) { filtered.add(p); } } StringBuffer buf = new StringBuffer(); for (Person p : filtered) { buf.append(p.getName() + "," + p.getAge() + "\n"); } return buf.toString(); } Java Q1. ্هͷίʔυͷҙਤΛ౴͑Αɻ ʢճ౴࣌ؒ: 10 ඵɺ഑఺: 5 ఺ʣ ίϨΫγϣϯ
  22. public String func(List<Person> persons) { List<Person> filtered = new ArrayList<Person>();

    for (Person p : persons) { if (p.getAge() >= 18) { filtered.add(p); } } StringBuffer buf = new StringBuffer(); for (Person p : filtered) { buf.append(p.getName() + "," + p.getAge() + "\n"); } return buf.toString(); } Java Q1. ্هͷίʔυͷҙਤΛ౴͑Αɻ ʢճ౴࣌ؒ: 10 ඵɺ഑఺: 5 ఺ʣ 18 ࡀະຬͷਓΛϑΟϧλ ֤ Person Λ CSV ʹม׵ ίϨΫγϣϯ
  23. def func(persons: List[Person]): String = persons .filter(p => p.age >=

    18) .map(p => p.name + “,” + p.age) .mkString(“,”) Scala Scala ίϨΫγϣϯͳΒ ؆ܿ͞ˍಡΈ΍͕͢͞UPʂ ίϨΫγϣϯ ม׵ࡁΈϦετ͕໭Γ஋ͳͷͰ ࣍ʑͱ࿈࠯Ͱ͖Δ
  24. def func(persons: List[Person]): String = persons .filter(p => p.age >=

    18) .map(p => p.name + “,” + p.age) .mkString(“,”) Scala Scala ίϨΫγϣϯͳΒ ؆ܿ͞ˍಡΈ΍͕͢͞UPʂ ίϨΫγϣϯ ม׵ࡁΈϦετ͕໭Γ஋ͳͷͰ ࣍ʑͱ࿈࠯Ͱ͖Δ ͜Ε͸Կʁ
  25. persons.filter(p => p.age >= 18) Scala ίʔϧόοΫΛ؆ܿʹॻ͚Δ౶ҥߏจ ͱ͍͏ཧղͰͱΓ͋͑ͣແ໰୊ͩͱࢥ͍·͢ɻ ίϨΫγϣϯ persons.filter(new

    Function1[Person, Boolean] { def apply(p: Person): Boolean = p.age >= 18 }) ʹ Person Λೖྗͯ͠ Boolean Λग़ྗ͢Δ p ΛҰͭͣͭ apply ʹ౉ͯ͠൑ఆ
  26. val ret = (1 to 10000000).par.map(_ + 1) Scala ී௨ͷίϨΫγϣϯΛ

    ؆୯ʹ ฒྻܭࢉରԠʹͰ͖Δʂ par Λݺͼग़͚ͩ͢ʂ ίϨΫγϣϯ
  27. I call it my billion-dollar mistake. It was the invention

    of the null reference in 1965. Tony Hoare (2009). “Null Reference: The Billion Dollar Mistake”. QCon London “null ͸ 10 ԯυϧͷࣦഊ” ※ʮΫΠοΫιʔτʯΛൃ໌ͨ͠ਓ Option ܕ
  28. sealed abstract class Option[+A] final case class Some[+A](x: A) extends

    Option[A] object None extends Option[Nothing] Option None -x: A Some ͦ͜Ͱ Option ܕ Option ܕ ”ࣦഊͨ͠ܭࢉ”ΛදݱͰ͖Δσʔλܕ case Ϋϥεʂ
  29. Option ܕΛ࢖͏ val person: Option[Person] = map.get(“tom”) person match {

    case Some(p) => println(p.name) case None => println(“no value!”) } ύλʔϯϚονͰ ҆શʹ஋ΛऔΓग़ͤΔ Option ܕ
  30. person match { case Some(p) => println p.name // If

    you forget ‘case None =>’... } warning: match may not be exhaustive. It would fail on the following input: None person match { ^ ίϯύΠϥ͕ ϛεΛݟ͚ͭͯܯࠂͯ͘͠ΕΔʂ Option ܕ ͏͔ͬΓ None Λ ๨Εͯ΋… ίϯύΠϥ: ʮNone ͷఆ͕ٛແ͘ͳ͍ʁʯ
  31. ίϨΫγϣϯԋࢉͱͷ૊Έ߹Θͤ person map { p => p.name // Someͷ͚࣌ͩ஋Λऔग़͠ }

    orElse { Some(“no value!”) // Noneͷ͚࣌ͩஔ͖׵͑Δ } foreach { name => println(name) // Someͷ͚࣌ͩग़ྗ } ώϯτ: Option ͸ཁૉ਺͕ 0 ͔ 1 ͷ List Option ܕ Ϧετͱಉ͡ϝιου…ʁ
  32. Optionͷ਌ੰ • ࣦഊͨ͠ཧ༝Λอ࣋Ͱ͖Δ • Either ܕ • Try ܕʢScala 2.10

    Ҏ߱ʣ • ࣦഊ͢Δ͔΋͠Εͳ͍ඇಉظܭࢉ • Future ܕʢScala 2.10 Ҏ߱ʣ Option ܕ
  33. શମͷ·ͱΊ • Scala ͸ ”Better Java”ɻ͜Θ͘ͳ͍Αʂ • “Better Java” ͚ͩ͡Όͳ͍

    • ”ܕͷྗ”Λ׆͔ͨ҆͠શͳϓϩάϥϛϯάɻ • ͦͯؔ͠਺ܕϓϩάϥϛϯά΁…ɻ