Scala學習筆記2

rilley發表於2014-09-22
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
object Basic extends App
{
    /*
    class WordCount
    {
        // Java
        public static void main(String[] args)
        {
            String tx = "Good morning !It is really my honor to have this opportunity is for a interview,I hope i can make is a good performance today";
 
            Map<String, Integer> count = new HashMap<String, Integer>();
            for (String word : tx.split(" ")) {
                int number = count.containsKey(word) ? count.get(word) : 0;
                count.put(word, number + 1);
            }
        }
    }
    */
 
 
    /*
    <?PHP
    // PHP
    $text = "Good morning !It is really my honor to have this opportunity is for a interview,I hope i can make is a good performance today";
 
    foreach (explode(" ", $text) as $w) $count[$w] += 1;
    ?>
    */
 
 
    /*
    # python
    text = "Good morning !It is really my honor to have this opportunity is for a interview,I hope i can make is a good performance today"
 
    count = {}
    for word in text.split(" "): count[word] = count[word] + 1 if word in count else 1
    */
 
 
    /*
    // Scala
    object WordCount extends App
    {
        val text = "Good morning !It is really my honor to have this opportunity is for a interview,I hope i can make is a good performance today"
 
        (Map[String, Int]() /: text.split(" ")) { (i, j) => i(j) = i.getOrElse(j, 0) + 1; i }
    }
    */
 
 
 
    // 基本型別
    //Byte, Char, Short, Int, Long, Float, Double, Boolean
    1.toChar; "10".toInt
 
 
 
   // 變數 不變數 其中var 與 val 的區別在於,var 是變數,以後的值還可以改變, val的值只能在宣告的時候賦值,但是val不是常量,只能說是不變數或只讀變數
    val answer = 8 5 2
    var conter = 0
    val greeting: String = "Hello"
 
 
 
    // 列印
    print("Answer: ")
    println("53")
 
 
 
    // 高階For迴圈
    1 to 10 // Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    1 until 10 // Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
 
    for (i <- 1 to 10) print(_)
    for (i <- 1 to 10if % 2 == 0) print(_)
    for (i <- 1 to 3; j <- 1 to 3 if i != j) print((10 * i + j) + " "// 12 13 21 23 31 32
    for (i <- 1 to 3; a = 4 - i; j <- a to 3) print((10 * i + j) + " "// 13 22 23 31 32 33
 
 
 
    // 匹配模式
    val num = 10
    num match {
        case if == 1 => println("one, a lonely number")
        case if (x == 2 || x == 3=> println(x)
        case _ => println("some other value")
    }
    val = num match {
        case if == 10 =5
        case "4" =6
        case _ =9
    }
 
 
    // 函式
    // 函式定義:
    def 方法名(引數名: 引數型別): 返回型別 =
    {
        //block內最後一一行行為返回值
    }
 
    當返回值為Unit時可以定義為:
    def 方法名(引數名: 引數型別)
    {
        //code
    }
 
 
    // 在Scala中,你需要為函式引數指定型別簽名。
    def addOne(m: Int): Int =
    {
        m + 1
    }
    addOne(2// 3
    // 如果函式不帶引數,你可以不寫括號。
    def three() = 1 2
    def three = 1 2
    three // 3
 
 
    // 匿名函式
    // 你可以傳遞匿名函式,或將其儲存成不變數。
    val addTwo = (x: Int) => x + 1
    addTwo(1// 2
    { i: Int =>
        println("hello world")
        i * 2
    }
 
 
    // 可變長度引數
    // 這是一個特殊的語法,可以向方法傳入任意多個同型別的引數。例如要在多個字串上執行String的capitalize函式,可以這樣寫:
    def capitalizeAll(args: String*) =
    {
        args.map { arg =>
            arg.capitalize
        }
    }
    capitalizeAll("rarity""applejack"// ArrayBuffer(Rarity, Applejack)
 
 
    // 偏函式
    trait PartialFunction[A, B] extends (A) => B
 
    // 偏函式recieve在akka的Actor起到關鍵作用。例如:
    case object Greet
    case class WhoToGreet(who: String)
    case class Greeting(message: String)
 
    class Greeter extends Actor
    {
        var greeting = ""
        def receive : Actor.Receive =
        {
            case WhoToGreet(who) => greeting = s"hello, $who"
            case Greet           => sender ! Greeting(greeting)
        }
    }
    //而Actor.Receive的定義為:type Receive = PartialFunction[Any, Unit]
    //偏函式receive以case object, case class為message Domain,返回Unit (即receive不會返回一個普通型別(如:String, Int等)值)

 

 

 

 

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
object Collection extends App
{
    // Map List Tuple Array Set Queue Stack
 
    // Array
    // 10個正數的陣列,所有元素初始化為0
    val nums = new Array[Int](10);
    val array = Array("Hello""World")
 
 
    // 變長陣列
    import scala.collection.mutable.ArrayBuffer
 
    val = ArrayBuffer[Int]()
 
    b += 1
    b += (123)
    b ++= Array(123)
    b(0// 取值
 
    // 迭代
    for (e <- b) println(e)
    b.foreach(e => println(e))
    b.foreach(println(_))
    b foreach println
 
 
 
    // Map
    import scala.collection.mutable.Map
 
    val source = Map("Alice" -> 10"Bob" -> 3"Cindy" -> 5)
    val jMap: HashMap[String, Int] = new HashMap[String, Int]()
 
    val item = source("Bob")
    source("Fred"= 7
    source += ("Bob" -> 10"Fred" -> 7)
 
    for ((k, v) <- source) println(s"$k => $v")
 
 
    // Tuple
    val tuple = (13,14"Fred")
 
    // Tuple3[Int, Doubel, java.lang.String]
    println(s"$tuple._1, $tuple._2, $tuple._3")
 
    // 模式匹配獲取元祖
    val (first, second, third) = tuple
 
 
 
    // List
    import scala.collection.mutable.ListBuffer
 
    val list = ListBuffer[Int]();
    list += 1
    list += 2
    list ++= List(345)
    list(0) + list(1) + list(2)
 
 
 
 
    // method [foreach filter map reduce sum max min count partition zip mkString]
    val names = List("Peter""Paul""Mary")
    val numbers = List(1234)
 
 
 
    // filter 移除任何使得傳入的函式返回false的元素。返回Boolean型別的函式一般都稱為斷言函式。
    names.filter(_.length < 5// List("Paul", "Mary")
    numbers.filter((i: Int) => i % 2 == 0// List(2, 4)
 
    def isEven(i: Int): Boolean = % 2 == 0
    numbers.filter(isEven _// List(2, 4)
 
 
 
    // map 在列表中的每個元素上計算一個函式,並且返回一個包含相同數目元素的列表。
    names.map(_.toUpperCase) // List("PETER", "PAUL", "MARY")
    numbers.map((i: Int) => i * 2// List(2, 4, 6, 8)
 
 
 
    // foreach和map相似,只不過它沒有返回值,foreach只要是為了對引數進行作用。
    numbers.foreach((i: Int) => i * 2//
 
 
 
    // reduce reduceLeft接受一個接受兩個引數的函式,reduceLeft會依次把前一次得到的結果和下一個列表元素傳遞給函式,最後得到一個單個元素
    List(2,4,6).reduceLeft(_+_// 12   相當於: ((2 + 4) + 6)
    List(1,4,9,6,7).reduceLeft( (x,y)=if (x>y) x else y ) // 9    ((((1 max 4) max 9) max 6) max 7)
 
 
 
    // sum max min count
    numbers.sum // 10
    numbers.max // 4
    numbers.min // 1
    numbers.count(_ 0// 4
 
 
 
    // partition
    val numList = List(12345678910)
    numList.partition(_ % 2 == 0// (List(2, 4, 6, 8, 10), List(1, 3, 5, 7, 9))
 
 
 
    // zip
    List(123).zip(List("a""b""c")) // List((1,a), (2,b), (3,c))
 
 
 
    // mkString
    names.mkString(", "// Peter, Paul, Mary
    names.mkString("<"", "">"// <Peter, Paul, Mary>
}

 

 

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
38
39
40
41
42
43
44
45
46
47
48
49
50
object Example extends App
{
    // 快速排序
    object QuickSort
    {
        def main(args: Array[String]): Unit =
        {
            var arrays = Array(1233435435233213);
            println("排序前的結果");
            arrays.foreach(println)
            arrays = sort(arrays);
            println("排序後的結果");
            arrays.foreach(println)
        }
 
        def sort(xs: Array[Int]): Array[Int] =
        {
            if(xs.length <= 1)
                xs;
            else {
                val pivot = xs(xs.length / 2);
                Array.concat(
                    sort(xs filter (pivot > _)), xs filter (pivot == _), sort(xs filter (pivot < _))
                )
            }
        }
    }
 
    // 使用蒙特卡洛方法計算Pi值
    object SparkPi
    {
        def main(args: Array[String])
        {
            val conf = new SparkConf().setAppName("Spark Pi")
            val spark = new SparkContext(conf)
 
            val slices = if (args.length > 0) args(0).toInt else 2
            val = 100000 * slices
 
            val count = spark.parallelize(1 to n, slices).map { i =>
                val = random * 2 1
                val = random * 2 1
                if (x * x + y * y < 11 else 0
            }.reduce(_ _)
 
            println("Pi is roughly " 4.0 * count / n)
            spark.stop()
        }
    }
}
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
object Object extends App
{
    // 類
    class Calculator
    {
        val brand: String = "HP"
        @BeanProperty var color: String = _
        def add(m: Int, n: Int): Int = m + n
    }
 
    val calc = new Calculator
 
    calc.add(12// 3
    calc.brand // "HP"
    calc.brand = "PH"
    // 在Scala中getter和setter方法並非被命名為getXxx和setXxx,不過他們的意思是相同的
 
 
    /* Java
    public class Person
    {
        private int age;
        public int getAge() { return age; }
        public void setAge(int age) { this.age = age; }
    }
    */
 
 
    // 繼承
    class ScientificCalculator(brand: String) extends Calculator(brand)
    {
        def log(m: Double, base: Double) = math.log(m) / math.log(base)
    }
 
 
 
    // 過載 & 重寫
    class EvenMoreScientificCalculator(brand: String) extends ScientificCalculator(brand)
    {
        def log(m: Int): Double = log(m, math.exp(1))
        override def add(x: Int, y: Int) = x + y
    }
 
 
    // 抽象類 你可以定義一個抽象類,抽象類可以定義一些方法,但是不需要實現它們。相反,繼承抽象類的子類需要實現這些方法。抽象類是不能被例項化的。
    abstract class Shape
    {
        def getArea():Int // subclass should define this
    }
 
    class Circle(r: Int) extends Shape
    {
        def getArea():Int = { r * r * 3 }
    }
 
 
    // 不能例項化一個抽象類
    val = new Shape // error: class Shape is abstract; cannot be instantiated val s = new Shape
    val = new Circle(2)
 
 
    // Traits traints表示一系列可以擴充套件或者混入到你的類裡的成員和行為。
    trait Car
    {
        val brand: String
    }
 
    trait Shiny
    {
        val shineRefraction: Int
    }
 
    class BMW extends Car
    {
        val brand = "BMW"
    }
 
    // 通過with關鍵字,一個類可以擴充套件多個traint:
    class BMW extends Car with Shiny
    {
        val brand = "BMW"
        val shineRefraction = 12
    }
 
    /*
    什麼時候你需要使用Trait代替抽象類? 如果你想定義一個類似介面的型別,
    那麼你很難在trait和抽象類之間做出選擇。它們都可以讓你定義一個具有某些行為的型別,
    然後要求擴充套件者去實習其他的行為。下面是一些經驗法則:
    優先使用traint。一個類可以擴充套件多個traint,但是隻能擴充套件一個抽象類。
    如果你需要在構造類的時候傳入引數的話,那就是用抽象類。抽象類的構造器可以傳入引數,trait則不能。
    例如,你不能這樣寫trait t(i:Int) {} ;引數i是非法的。
    */
 
 
    // 伴生類
    class Pizza (var crustType: String)
    {
        override def toString = "Crust type is " + crustType
    }
 
    object Pizza
    {
        val CRUST_TYPE_THIN = "thin"
        val CRUST_TYPE_THICK = "thick"
        def getFoo = "Foo"
    }
 
    var = new Pizza(Pizza.CRUST_TYPE_THICK)
}

相關文章