Scala: One more step forward
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
1Array(element1, element2, ...) -
You can declare type of Array like
123Array[Int]//orArray[String] -
To print nicely an Array’s content
1array_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
123class 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
12345678910111213def 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
12345678val array4 = Array(1, 2, 3, 4, 5)println(array4(0))array4(0) = 6println(array4(0))println(array4.indexOf("3")) // -1println(array4.indexOf(3)) // 2 - Concatenation
1234// Concatenation using the ++ operator,// Prepending items using +: and appending using :+val concatenated = 1 +: (array1 ++ array4) :+ 2printArray(concatenated) - Diff
12val diffArray = Array(1,2,3,4).diff(Array(2,3))printArray(diffArray) -
Contains
12val 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
1List(element1, element2, ...) -
List elements can be of any type
123class 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
1234567//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
12345import collection.mutable//the "mutable version" of Listval mlist = mutable.ArrayBuffer("a", "b", "c")def printStringList(list:mutable.ArrayBuffer[String]) = println(list.mkString("String List(" , ", " , ")"))printStringList(mlist) - Using (index)
12345val firstItem = list1(0) // firstItem = 1//Modify items the same way (mutable Lists only)mlist(0) = "d"mlist -
Concatenation
123456789101112131415// 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 togetherval 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 themselveslist1 // List(1, 2, 3) - Access elements
123456789101112131415161718192021222324//Removing elements (mutable list only, creates a new array)://creates a new array with "c" removed, mlist is not touchedmlist - "c" // ArrayBuffer(d, b)//creates a new array with e, f removed, mlist is not touchedmlist -- List("e", "f") // ArrayBuffer(d, b, c)//mlist not modifiedmlist // ArrayBuffer(d, b, e, f, g)//Removing elements (mutable Lists only)://removes c from the list itselfmlist -= "c" // ArrayBuffer(d, b, e, f, g)mlist // ArrayBuffer(d, b, e, f, g)//removes e and f from mlist itselfmlist --= 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)//Diffval 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
1234val 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
123import collection.mutableval mmap = mutable.HashMap("a" -> 1, "b" -> 2 , "c" -> 3)//the "mutable version" of Map -
Cannot duplicate key
12//Maps remove duplicate keys:println(Map("a" -> 1, "a" -> 2)) //Map(a -> 2) -
Access Items
1234567891011121314151617181920212223val 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 laterval fourExistsOption = map1.get("four")println(one) // 1println(fourExistsOption.isDefined) // false//You can set / modify items using map(key) = valuemmap("d") = 4println(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" -> 5mmap ++= Map("f" -> 6, "g" -> 7) -
Concatenation
1234567//Concatenation using the ++ operator//(removes duplicate keys, order not guaranteed)val concatenated = map1 ++ map2 ++ mmapprintln(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 themselvesprintln(map1) //Map(one -> 1, two -> 2, three -> 3) -
Find elements
12345678//Findval 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) //2println(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
1class 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
1class 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
Practice
12345678910111213141516171819202122232425262728293031323334353637
//Simple class that does nothing class Person(fname:String, lname:String) val p1 = new Person("Alice", "In Chains") //p1.fname / lname is not accessible //A class with a method class Person2(fname:String, lname:String){ def greet = s"Hi $fname $lname!" } val p2 = new Person2("Bob", "Marley") println(p2.greet) //p2.fname / lname is not accessible //A class with a public read only variable class Person3(fname:String, lname:String){ // a public read only field val fullName = s"$fname $lname" def greet = s"Hi $fullName!" } val p3 = new Person3("Carlos", "Santana") println(p3.greet) println(p3.fullName) //p3.fname / lname is not accessible //auto creates a getter for fname, and getter + setter to lname class Person4(val fname:String, var lname:String) val p4 = new Person4("Dave", "Matthews") { //override the default string representation override def toString = s"$fname $lname" } println(p4.fname) println(p4.lname) //lname is defined as var, so it has a setter too p4.lname = "Grohl" println(p4)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
//Simple class that does nothing class Person(fname:String, lname:String) val p1 = new Person("Alice", "In Chains") //p1.fname / lname is not accessible //A class with a method class Person2(fname:String, lname:String){ def greet = s"Hi $fname $lname!" } val p2 = new Person2("Bob", "Marley") println(p2.greet) //p2.fname / lname is not accessible //A class with a public read only variable class Person3(fname:String, lname:String){ // a public read only field val fullName = s"$fname $lname" def greet = s"Hi $fullName!" } val p3 = new Person3("Carlos", "Santana") println(p3.greet) println(p3.fullName) //p3.fname / lname is not accessible //auto creates a getter for fname, and getter + setter to lname class Person4(val fname:String, var lname:String) val p4 = new Person4("Dave", "Matthews") { //override the default string representation override def toString = s"$fname $lname" } println(p4.fname) println(p4.lname) //lname is defined as var, so it has a setter too p4.lname = "Grohl" println(p4) |