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  10 if  %  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 + =  ( 1 2 3 )
     b ++ =  Array( 1 2 3 )
     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  =  ( 1 3 , 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( 3 4 5 )
     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( 1 2 3 4 )
 
 
 
     // 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( 1 2 3 4 5 6 7 8 9 10 )
     numList.partition( _  %  2  ==  0 // (List(2, 4, 6, 8, 10), List(1, 3, 5, 7, 9))
 
 
 
     // zip
     List( 1 2 3 ).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( 123 343 5435 23 3213 );
             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 <  1 1  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( 1 2 // 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)