首页 > 代码库 > Scala学习笔记2

Scala学习笔记2

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)
}

Scala学习笔记2