Scala: One more step forward
September 16, 2014
Hi all,
In two previous posts, I have guided you to prepare the environment, install IDE, and some basic of Scala. You can refer to the first part here, or the second part here
Today, I write the second part of Scala, focus on Arrays, Lists, Maps And Classes
Please note that the original tutorials: http://scalatutorials.com
Arrays
Introduction
- Arrays construct
Array(element1, element2, ...)
- You can declare type of Array like
Array[Int] //or Array[String]
- To print nicely an Array’s content
array_name.mkString(",")
- Arrays are mutable (can’t change it’s size once created, but can modify it’s elements)
- Array elements can be of any type
class Foo(val value1:Int) class Bar(value1:Int, val value2:Int) extends Foo(value1) val list:Array[Foo] = Array(new Foo(1), new Bar(2,3))
Practice
- Write function that print Array elements
def printArray(array:Array[Int]) = println(array.mkString("Array(" , ", " , ")")) // Mutable array of type Array[Int] val array1 = Array(1, 2, 3) printArray(array1)//>Array(1, 2, 3) // Mutable array of type Array[String] val array2 = Array("a", "b", "c") printArray(array2) // Mutable array of type Array[Any] val array3 = Array("a", 2, true) printArray(array3)
- Array index
val array4 = Array(1, 2, 3, 4, 5) println(array4(0)) array4(0) = 6 println(array4(0)) println(array4.indexOf("3")) // -1 println(array4.indexOf(3)) // 2
- Concatenation
// Concatenation using the ++ operator, // Prepending items using +: and appending using :+ val concatenated = 1 +: (array1 ++ array4) :+ 2 printArray(concatenated)
- Diff
val diffArray = Array(1,2,3,4).diff(Array(2,3)) printArray(diffArray)
- Contains
val A = Array((1,2),(3,4)) println(A contains (1,2))
And many, many other APi you can find on Scala site: http://www.scala-lang.org/api/current/index.html#scala.Array
List
Introduction
- Construct
List(element1, element2, ...)
- List elements can be of any type
class Foo(val value1:Int) class Bar(value1:Int, val value2:Int) extends Foo(value1) val list:List[Foo] = List(new Foo(1), new Bar(2,3))
- Reference: http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List
- The default List is implemented as a Linked list
- It is immutable (any “changes” craete a new list, the original is untouched)
Practice
- Declare Immutable List
//Immutable list of type List[Int] val list1 = List(1, 2, 3) // list1 = List(1, 2, 3) //Immutable list of type List[Any] val list2 = List("a", 2, true) // list2 = List(a, 2, true) def printIntegerList(list:List[Int]) = println(list.mkString("List(" , ", " , ")")) printIntegerList(_list1)
- Mutable list
import collection.mutable //the "mutable version" of List val mlist = mutable.ArrayBuffer("a", "b", "c") def printStringList(list:mutable.ArrayBuffer[String]) = println(list.mkString("String List(" , ", " , ")")) printStringList(mlist)
- Using (index)
val firstItem = list1(0) // firstItem = 1 //Modify items the same way (mutable Lists only) mlist(0) = "d" mlist
- Concatenation
// using the ++ operator or ::: (lists only) list1 ++ list2 // List(1, 2, 3, a, 2, true) list1 ::: list2 // List(1, 2, 3, a, 2, true) //Prepending an item using either :: (lists only) or +: 0 :: list1 // List(0, 1, 2, 3) 0 +: list1 // List(0, 1, 2, 3) //appending an item using :+ (not efficient for immutable List) list1 :+ 4 // List(1, 2, 3, 4) //all together val concatenated = 1 :: list1 ::: list2 ++ mlist :+ 'd' // concatenated = List(1, 1, 2, 3, a, 2, true, d, b, c, d) //concatenation doesn't modify the lists themselves list1 // List(1, 2, 3)
- Access elements
//Removing elements (mutable list only, creates a new array): //creates a new array with "c" removed, mlist is not touched mlist - "c" // ArrayBuffer(d, b) //creates a new array with e, f removed, mlist is not touched mlist -- List("e", "f") // ArrayBuffer(d, b, c) //mlist not modified mlist // ArrayBuffer(d, b, e, f, g) //Removing elements (mutable Lists only): //removes c from the list itself mlist -= "c" // ArrayBuffer(d, b, e, f, g) mlist // ArrayBuffer(d, b, e, f, g) //removes e and f from mlist itself mlist --= List("e", "f") // ArrayBuffer(d, b, e, f, g) mlist // ArrayBuffer(d, b, e, f, g) //Adding elements (mutable Lists only) mlist += "e" // ArrayBuffer(d, b, e, f, g) mlist ++= List("f", "g") // ArrayBuffer(d, b, e, f, g) mlist //ArrayBuffer(d, b, e, f, g) // ArrayBuffer(d, b, e, f, g) //Diff val diffList = List(1,2,3,4) diff List(2,3) // diffList = List(1, 4)
Maps
Introduction
- Maps are constructed simply using Map(key1 -> value1, key2 -> value2, …)
- The default Map is Predef.Map which points to scala.collection.immutable.Map
- You can’t have duplicate keys, adding a key value pair whose key already exists, overwrites the value
- Order of iteration is not guaranteed to be consistent
Practice
- Immutable Construction
val map1 = Map("one" -> 1, "two" -> 2, "three" -> 3) //Map of type Map[String, Int] val map2 = Map(1 -> "one", "2" -> 2.0, 3.0 -> false) //Map of type Map[Any, Any]
- Mutable Construction
import collection.mutable val mmap = mutable.HashMap("a" -> 1, "b" -> 2 , "c" -> 3) //the "mutable version" of Map
- Cannot duplicate key
//Maps remove duplicate keys: println(Map("a" -> 1, "a" -> 2)) //Map(a -> 2)
- Access Items
val one = map1("one") //NoSuchElementException will be thrown if key doesn't exist! //e.g. this code: val fourExists = map1("four") //throws NoSuchElementException: key not found: four //the get method returns an Option, which will be explained later val fourExistsOption = map1.get("four") println(one) // 1 println(fourExistsOption.isDefined) // false //You can set / modify items using map(key) = value mmap("d") = 4 println(mmap) //Map(b -> 2, d -> 4, a -> 1, c -> 3) //Removing elements (mutable Sets only) mmap -= "c" println (mmap) //Map(b -> 2, d -> 4, a -> 1) //Adding elements (mutable Lists only) mmap += "e" -> 5 mmap ++= Map("f" -> 6, "g" -> 7)
- Concatenation
//Concatenation using the ++ operator //(removes duplicate keys, order not guaranteed) val concatenated = map1 ++ map2 ++ mmap println(concatenated) // Map(three -> 3, 1 -> one, two -> 2, a -> 1, b -> 2, 3.0 -> false, 2 -> 2.0, c -> 3, one -> 1, d -> 4) //Concatenation doesn't modify the maps themselves println(map1) //Map(one -> 1, two -> 2, three -> 3)
- Find elements
//Find val personMap = Map(("Alice",1), ("Bob",2), ("Carol",3)) def findByName(name:String) = personMap.getOrElse(name, 4) val findBob = findByName("Bob") val findEli = findByName("Eli") println(findBob) //2 println(findEli) //4
Classes
Introduction
- The class body, is also the default constructor’s implementation
- Automatic getters are generated for the class parameters defined using
val
class Person(val name:String) //generates a private `name` variable, and a getter with the same name
- Automatic getters and setters are generated for class parameters defined using
var
class Person(var name:String) //generates a private name variable, a getter and a setter with the same name
- Everything is public by default unless explicity declared otherwise