17.	
  Collec*ons	

   Joongjin	
  Bae	
  
  Ameba:dudug	
  
  twi;er:bae_j
Index	
•  Sequences	
  
    –  Lists,	
  Arrays,	
  List	
  buffers,	
  Array	
  buffers,	
  StringOps	
  
•  Sets	
  and	
  Maps	
  
    –  Using	
  Sets	
  and	
  Maps,	
  Default,	
  Sorted	
  
•  Mutable	
  vs.	
  Immutable	
  collec*ons	
  
•  Ini*alizing	
  collec*ons	
  
    –  Conver*ng	
  array	
  or	
  list,	
  mutable	
  and	
  immutable	
  
       sets	
  and	
  maps	
  	
  
•  Tuples	
  
Sequences	

Array	
  Listは触れません
ListBuffer	
Listは先頭からは速いが末尾からは遅い。	
  
Listを逆にして先頭から接続するか	
  
ListBufferを利用する。	
  
ListBufferはmutableであり、append,	
  prepend演
算(opera*on)可能	
  
+=	
  append	
  (ex	
  buf	
  +=	
  1)	
  
+=:	
  prepend	
  (ex	
  4	
  +=:	
  buf)	
  
=>	
  buf.type	
  =	
  ListBuffer(4,1)	
  
ListBuffer	
•  buf.toListでList取得可能	
  
•  Listの代わりにListBufferを使う理由はstack	
  
   overflowを回避するため	
  
  –  詳細は22章で
ArrayBuffer	
•  ListBuffer同様、mutable,	
  append,	
  prepend可
   能	
  
   –  buf	
  +=	
  12	
  
   –  14	
  +=:	
  buf	
  
   –  buf.toArray	
  =>	
  Array	
  (14,	
  12)	
  
•  scala.collec*on.mutable.ArrayBuffer	
  import必
   須	
  
•  buf.length	
  =>	
  2,	
  buf(0)	
  =>	
  14	
  利用可能	
  
ArrayBuffer	
•  前後から接続、追加、削除可能	
  
•  Arrayのすべての操作可能、ちょっと遅い	
  
  –  Wrapperだから	
  
•  追加/削除は平均O(1)(constant	
  *me	
  on	
  
   average)がたまにO(n)になる	
  
  –  配列の再構築が必要だから
StringOps	
def	
  hasUpperCase(s:	
  String)	
  =	
  s.exists(_.isUpper)	
  
hasUpperCase(“Scala”)	
  =>	
  true	
  
hasUpperCase(“scala”)	
  =>	
  false	
  
	
  
Stringはexistsメソッドがない。	
  
なぜ実行出来る?
StringOps	
•  コンパイラがs	
  Stringを暗黙的にStringOpsへ
   変換し実行する	
  
•  existsメソッドはcharの配列として扱い
Sets	
  and	
  maps	

使い方は触れません
Default	
  sets	
  and	
  maps	
•  Set(),	
  Map()で簡単に生成できる。	
  
•  速いアルゴリズム(hashtable)を使ってobject
   がcollec*onの中に存在するか判断	
  
•  mutable.Set(),	
  mutable.Map()は	
  
   HashSet,	
  HashMapを生成	
  
•  immutableの場合、要素数によって違うobject
   を返す
Default	
  sets	
  and	
  maps	

              immutable.Set()	
要素数	
                   実装	
0	
                     immutable.EmptySet	
1	
                     immutable.Set1	
2	
                     immutable.Set2	
3	
                     immutable.Set3	
4	
                     immutable.Set4	
5	
                     immutable.HashSet
Default	
  sets	
  and	
  maps	

            immutable.Map()	
要素数	
                   実装	
0	
                     immutable.EmptyMap	
1	
                     immutable.Map1	
2	
                     immutable.Map2	
3	
                     immutable.Map3	
4	
                     immutable.Map4	
5	
                     immutable.HashMap
Sorted	
  sets	
  and	
  maps	
•  SortedSet,	
  SortedMap提供(Trait)	
  
•  赤黒木を使ったTreeSet,	
  TreeMapで実装され
   ている。	
  
mutable	
  vs.	
  immutable	
•  mutableがよく動く場合とimmutableがよく動く
   場合がある。	
  
•  どちを使うか迷う場合はimmutableを使う。	
  
 –  後でmutableへ変換すれば良い	
  
 –  サイズが小さい
mutable	
  vs.	
  immutable	
•  scalaはimmutableómutable変換しやすくす
   るsyntac*c	
  sugarを提供	
  
  –  immutableの場合	
  +=	
  メソッドが定義されてない	
  
  –  interpreterが	
  a	
  +=	
  b	
  =>	
  a	
  =	
  a	
  +	
  bに解析
+=	
  example	
val	
  people	
  =	
  Set(“B”,	
  “土橋”)	
  
people	
  +=	
  “木本”	
  
	
  
var	
  people	
  =	
  Set(“B”,	
  “土橋”)	
  
people	
  +=	
  “木本”	
  
	
  
-­‐=	
  ++=	
  例	
people	
  -­‐=	
  “B”	
  
people	
  ++=	
  List(“Bae”,	
  “Kim”)	
  
people	
  ?	
  
	
  
immutable.Set[java.lang.String]	
  =	
  Set(土橋,	
  木
本,	
  Bae,	
  Kim)	
  
Ini*alizing	
  collec*ons	
•  factoryメソッドの引数として渡す	
  
  –  List(1,2,3)	
  
  –  Set(‘a’,’b,’c’)	
  
  –  mutable.Map(“hi”	
  -­‐>	
  2,	
  “there”	
  -­‐>	
  5)	
  
•  コンパイラが適切な型を設定する。	
  
  –  List[Int]	
  
  –  Set[Char]	
  
  –  mutable.Map[String,	
  Int]	
  
Ini*alizing	
  collec*ons	
•  この場合は?	
  
val	
  stuff	
  =	
  mutable.Set(42)	
  
stuff	
  +=	
  “abc”	
  
	
  
最初生成時IntになっているためStringは追加で
きない。	
  
解決:val	
  stuff	
  =	
  mutable.Set[Any](42)
Ini*alizing	
  collec*ons	
•  collec*on生成時collec*onを引数として渡した
   い場合	
  
val	
  colors	
  =	
  List(“red”,	
  “blue”)	
  
val	
  treeSet	
  =	
  TreeSet(colors)	
  =>	
  error	
  
val	
  treeSet	
  =	
  TreeSet()	
  ++	
  colors	
  
Conver*ng	
  to	
  array	
  or	
  list	
•  Just	
  invoke	
  toList/toArray	
  
   –  treeSet.toArray	
  
   –  colors.toArray	
  
•  toArrayの結果は?	
  
   –  treeSet	
  (blue,	
  red)	
  
   –  colors	
  (red,	
  blue)	
  
•  toList/toArrayはcollec*onのコピーなのでコス
   トに注意
Conver*ng	
  mutable	
  ó	
  immutable	
treeSet	
  =>	
  (blue,	
  red)	
  
val	
  mutaSet	
  =	
  mutable.Set.empty	
  ++=	
  treeSet	
  
val	
  immutaSet	
  =	
  Set.empty	
  ++	
  mutaSet
Tuples	
•  異なるtype	
  objectを持つ配列	
  
  –  (1,	
  “hello”,	
  Console)	
  
•  Javaの場合複数の戻り値を返したい場合、
   DTO又はPairクラス等を実装する必要有り	
  
•  ScalaはTupleを使えば簡単
Tuple使い方	
def	
  longestWord(words:	
  Array[String])	
  =	
  {	
  
	
  	
  var	
  word	
  =	
  words(0)	
  
	
  	
  var	
  idx	
  =	
  0	
  
	
  	
  for	
  (i	
  <-­‐	
  1	
  un*l	
  words.length)	
  
	
  	
  	
  	
  if	
  (words(i).length	
  >	
  word.length)	
  {	
  
	
  	
  	
  	
  	
  	
  word	
  =	
  words(i)	
  
	
  	
  	
  	
  	
  	
  idx	
  =	
  i	
  
	
  	
  	
  	
  }	
  
	
  	
  (word,	
  idx)	
  
}
Tuple使い方	
val	
  longest	
  =	
  longestWord(“The	
  quick	
  brown	
  
fox”.split(“	
  ”)	
  
	
  	
  	
  	
  	
  	
  	
  result	
  =>	
  (quick,	
  1)	
  
	
  
•  結果のTupleを使う場合_1,	
  _2を利用	
  
   –  longest._1	
  =>	
  quick	
  
   –  longest._2	
  =>	
  1	
  
   	
  
Tuple使い方	
–  val	
  (word,	
  idx)	
  =	
  longest	
  
   word:	
  String	
  =	
  quick	
  
   idx:	
  Int	
  =	
  1	
  
–  val	
  word,	
  idx	
  =	
  longest	
  
   word:	
  (String,	
  Int)	
  =	
  (quick,	
  1)	
  
   idx:	
  (String,	
  Int)	
  =	
  (quick,	
  1)

Programming in Scala Chapter 17 Collections

  • 1.
    17.  Collec*ons Joongjin  Bae   Ameba:dudug   twi;er:bae_j
  • 2.
    Index •  Sequences   –  Lists,  Arrays,  List  buffers,  Array  buffers,  StringOps   •  Sets  and  Maps   –  Using  Sets  and  Maps,  Default,  Sorted   •  Mutable  vs.  Immutable  collec*ons   •  Ini*alizing  collec*ons   –  Conver*ng  array  or  list,  mutable  and  immutable   sets  and  maps     •  Tuples  
  • 3.
  • 4.
    ListBuffer Listは先頭からは速いが末尾からは遅い。   Listを逆にして先頭から接続するか   ListBufferを利用する。   ListBufferはmutableであり、append,  prepend演 算(opera*on)可能   +=  append  (ex  buf  +=  1)   +=:  prepend  (ex  4  +=:  buf)   =>  buf.type  =  ListBuffer(4,1)  
  • 5.
    ListBuffer •  buf.toListでList取得可能   • Listの代わりにListBufferを使う理由はstack   overflowを回避するため   –  詳細は22章で
  • 6.
    ArrayBuffer •  ListBuffer同様、mutable,  append,  prepend可 能   –  buf  +=  12   –  14  +=:  buf   –  buf.toArray  =>  Array  (14,  12)   •  scala.collec*on.mutable.ArrayBuffer  import必 須   •  buf.length  =>  2,  buf(0)  =>  14  利用可能  
  • 7.
    ArrayBuffer •  前後から接続、追加、削除可能   • Arrayのすべての操作可能、ちょっと遅い   –  Wrapperだから   •  追加/削除は平均O(1)(constant  *me  on   average)がたまにO(n)になる   –  配列の再構築が必要だから
  • 8.
    StringOps def  hasUpperCase(s:  String)  =  s.exists(_.isUpper)   hasUpperCase(“Scala”)  =>  true   hasUpperCase(“scala”)  =>  false     Stringはexistsメソッドがない。   なぜ実行出来る?
  • 9.
    StringOps •  コンパイラがs  Stringを暗黙的にStringOpsへ 変換し実行する   •  existsメソッドはcharの配列として扱い
  • 10.
  • 11.
    Default  sets  and  maps •  Set(),  Map()で簡単に生成できる。   •  速いアルゴリズム(hashtable)を使ってobject がcollec*onの中に存在するか判断   •  mutable.Set(),  mutable.Map()は   HashSet,  HashMapを生成   •  immutableの場合、要素数によって違うobject を返す
  • 12.
    Default  sets  and  maps immutable.Set() 要素数 実装 0 immutable.EmptySet 1 immutable.Set1 2 immutable.Set2 3 immutable.Set3 4 immutable.Set4 5 immutable.HashSet
  • 13.
    Default  sets  and  maps immutable.Map() 要素数 実装 0 immutable.EmptyMap 1 immutable.Map1 2 immutable.Map2 3 immutable.Map3 4 immutable.Map4 5 immutable.HashMap
  • 14.
    Sorted  sets  and  maps •  SortedSet,  SortedMap提供(Trait)   •  赤黒木を使ったTreeSet,  TreeMapで実装され ている。  
  • 15.
    mutable  vs.  immutable • mutableがよく動く場合とimmutableがよく動く 場合がある。   •  どちを使うか迷う場合はimmutableを使う。   –  後でmutableへ変換すれば良い   –  サイズが小さい
  • 16.
    mutable  vs.  immutable • scalaはimmutableómutable変換しやすくす るsyntac*c  sugarを提供   –  immutableの場合  +=  メソッドが定義されてない   –  interpreterが  a  +=  b  =>  a  =  a  +  bに解析
  • 17.
    +=  example val  people  =  Set(“B”,  “土橋”)   people  +=  “木本”     var  people  =  Set(“B”,  “土橋”)   people  +=  “木本”    
  • 18.
    -­‐=  ++=  例 people  -­‐=  “B”   people  ++=  List(“Bae”,  “Kim”)   people  ?     immutable.Set[java.lang.String]  =  Set(土橋,  木 本,  Bae,  Kim)  
  • 19.
    Ini*alizing  collec*ons •  factoryメソッドの引数として渡す   –  List(1,2,3)   –  Set(‘a’,’b,’c’)   –  mutable.Map(“hi”  -­‐>  2,  “there”  -­‐>  5)   •  コンパイラが適切な型を設定する。   –  List[Int]   –  Set[Char]   –  mutable.Map[String,  Int]  
  • 20.
    Ini*alizing  collec*ons •  この場合は?   val  stuff  =  mutable.Set(42)   stuff  +=  “abc”     最初生成時IntになっているためStringは追加で きない。   解決:val  stuff  =  mutable.Set[Any](42)
  • 21.
    Ini*alizing  collec*ons •  collec*on生成時collec*onを引数として渡した い場合   val  colors  =  List(“red”,  “blue”)   val  treeSet  =  TreeSet(colors)  =>  error   val  treeSet  =  TreeSet()  ++  colors  
  • 22.
    Conver*ng  to  array  or  list •  Just  invoke  toList/toArray   –  treeSet.toArray   –  colors.toArray   •  toArrayの結果は?   –  treeSet  (blue,  red)   –  colors  (red,  blue)   •  toList/toArrayはcollec*onのコピーなのでコス トに注意
  • 23.
    Conver*ng  mutable  ó  immutable treeSet  =>  (blue,  red)   val  mutaSet  =  mutable.Set.empty  ++=  treeSet   val  immutaSet  =  Set.empty  ++  mutaSet
  • 24.
    Tuples •  異なるtype  objectを持つ配列   –  (1,  “hello”,  Console)   •  Javaの場合複数の戻り値を返したい場合、 DTO又はPairクラス等を実装する必要有り   •  ScalaはTupleを使えば簡単
  • 25.
    Tuple使い方 def  longestWord(words:  Array[String])  =  {      var  word  =  words(0)      var  idx  =  0      for  (i  <-­‐  1  un*l  words.length)          if  (words(i).length  >  word.length)  {              word  =  words(i)              idx  =  i          }      (word,  idx)   }
  • 26.
    Tuple使い方 val  longest  =  longestWord(“The  quick  brown   fox”.split(“  ”)                result  =>  (quick,  1)     •  結果のTupleを使う場合_1,  _2を利用   –  longest._1  =>  quick   –  longest._2  =>  1    
  • 27.
    Tuple使い方 –  val  (word,  idx)  =  longest   word:  String  =  quick   idx:  Int  =  1   –  val  word,  idx  =  longest   word:  (String,  Int)  =  (quick,  1)   idx:  (String,  Int)  =  (quick,  1)