1 /**
2 * 《chang哥教你一天搞定Scala》
3 * scala是一門多范式編程語言,集成了面向?qū)ο缶幊毯秃瘮?shù)式編程等多種特性。
4 * scala運行在虛擬機上,并兼容現(xiàn)有的Java程序。
5 * Scala源代碼被編譯成java字節(jié)碼,所以運行在JVM上,并可以調(diào)用現(xiàn)有的Java類庫。
6 */
7
8 /**
9 * 第一個Scala程序
10 * Scala和Java最大的區(qū)別是:Scala語句末尾的分號(;)是可選的!
11 * 編譯運行:
12 * 先編譯:scalac HelloScala.scala 將會生成兩個文件:HelloScala$.class和HelloScala.class
13 * 在運行:scala HelloScala
14 * 輸出結(jié)果:hello scala!!!
15 *
16 * object HelloScala{
17 def main(args: Array[String]): Unit = {
18 println("hello scala!!!")
19 }
20 }
21 */
22
23 /**
24 * Scala基本語法:
25 * 區(qū)分大小寫
26 * 類名首字母大寫(MyFirstScalaClass)
27 * 方法名稱第一個字母小寫(myMethodName())
28 * 程序文件名應(yīng)該與對象名稱完全匹配
29 * def main(args:Array[String]):scala程序從main方法開始處理,程序的入口。
30 *
31 * Scala注釋:分為多行/**/和單行//
32 *
33 * 換行符:Scala是面向行的語言,語句可以用分號(;)結(jié)束或換行符(println())
34 *
35 * 定義包有兩種方法:
36 * 1、package com.ahu
37 * class HelloScala
38 * 2、package com.ahu{
39 * class HelloScala
40 * }
41 *
42 * 引用:import java.awt.Color
43 * 如果想要引入包中的幾個成員,可以用selector(選取器):
44 * import java.awt.{Color,Font}
45 * // 重命名成員
46 * import java.util.{HashMap => JavaHashMap}
47 * // 隱藏成員 默認情況下,Scala 總會引入 java.lang._ 、 scala._ 和 Predef._,所以在使用時都是省去scala.的
48 * import java.util.{HashMap => _, _} //引入了util包所有成員,但HashMap被隱藏了
49 */
50
51 /**
52 * Scala數(shù)據(jù)類型:
53 * Scala與Java有著相同的數(shù)據(jù)類型,下面列出一些Scala有的數(shù)據(jù)類型。
54 * Unit:表示無值,和其他語言的void一樣。
55 * Null:null或空引用。
56 * Nothing:是Scala的類層級的最低端,是任何其他類型的子類型。
57 * Any:是所有其他類的超類。
58 * AnyRef:是Scala所有引用類的基類。
59 *
60 * 多行字符串的表示方法:
61 val foo ="""第一行
62 第二行
63 第三行"""
64 */
65
66 /**
67 * Scala變量:
68 * 在Scala中,使用關(guān)鍵字“var”聲明變量,使用關(guān)鍵字“val”聲明常量。
69 * var myVar1 : String = "foo"
70 * var myVar2 : Int
71 * val myVal = "Hello,Scala!"
72 * Scala多個變量聲明:
73 * val xmax, ymax = 100 // xmax,ymax都聲明為100
74 */
75
76 /**
77 * Scala訪問修飾符:
78 * Scala訪問修飾符和Java基本一樣,分別有private、protected、public。
79 * 默認情況下,Scala對象的訪問級別是public。
80 *
81 * 私有成員:用private關(guān)鍵字修飾的成員僅在包含了成員定義的類或?qū)ο髢?nèi)部可見。
82 * class Outer{
83 * class Inner{
84 * private def f(){println("f")}
85 * class InnerMost{
86 * f() // 正確
87 * }
88 * (new Inner).f() // 錯誤
89 * }
90 * }
91 *
92 * 保護成員:Scala比Java中更嚴格。只允許保護成員在定義了該成員的類的子類中被訪問。
93 * package p{
94 * class Super{
95 * protected def f() {println("f")}
96 * }
97 * class Sub extends Super{
98 * f()
99 * }
100 * class Other{
101 * (new Super).f() // 錯誤
102 * }
103 * }
104 *
105 * 公共成員:默認public,這樣的成員在任何地方都可以被訪問。
106 * class Outer{
107 * class Inner{
108 * def f(){println("f")}
109 * class InnerMost{
110 * f() // 正確
111 * }
112 * }
113 * (new Inner).f() // 正確
114 * }
115 *
116 * 作用域保護:Scala中,訪問修飾符可以通過使用限定詞強調(diào)。
117 * private[x] 或者 protected[x]
118 * private[x]:這個成員除了對[...]中的類或[...]中的包中的類及他們的伴生對象可見外,對其他的類都是private。
119 */
120
121 /**
122 * Scala運算符:和Java一樣,這里就不再浪費時間一一介紹了。
123 * 算術(shù)運算符、關(guān)系運算符、邏輯運算符、位運算符、賦值運算符。
124 */
125
126 /**
127 * Scala if...else語句:和Java一樣,簡單列舉一下四種情況。
128 * if(...){
129 *
130 * }
131 *
132 * if(...){
133 *
134 * }else{
135 *
136 * }
137 *
138 * if(...){
139 *
140 * }else if(...){
141 *
142 * }else{
143 *
144 * }
145 *
146 * if(...){
147 * if(...){
148 *
149 * }
150 * }
151 */
152
153 /**
154 * Scala循環(huán):和Java一樣,這里不贅述,只介紹三種循環(huán)類型。
155 * while循環(huán)、do...while循環(huán)、for循環(huán)
156 */
157
158 /**
159 * Scala函數(shù):用一個例子來說明函數(shù)的定義和函數(shù)調(diào)用。
160 * object Test{
161 * def main(args: Array[String]){
162 * println(addInt(1,3)); // 函數(shù)調(diào)用
163 * }
164 * def addInt(a:Int, b:Int) : Int = { // 函數(shù)定義
165 * var sum:Int = 0
166 * sum = a + b
167 * return sum
168 * }
169 * }
170 */
171
172 /**
173 * Scala閉包:
174 * 閉包是一個函數(shù),返回值依賴于聲明在函數(shù)外部的一個或多個變量。
175 * 例子:
176 * object Test{
177 * def main(args: Array[String]){
178 * println("muliplier(1) value = " + muliplier(1))
179 * println("muliplier(2) value = " + muliplier(2))
180 * }
181 * var factor = 3 // 定義在函數(shù)外的自由變量
182 * val muliplier = (i:Int) => i * factor // muliplier函數(shù)變量就是一個閉包
183 * }
184 * 輸出結(jié)果:
185 * muliplier(1) value = 3
186 * muliplier(2) value = 6
187 */
188
189 /**
190 * Scala字符串:
191 *
192 * Scala中可以創(chuàng)建兩中字符串:一種是不可修改的,一種是可以修改的。
193 * // 創(chuàng)建不可修改的字符串
194 * val greeting:String = "Hello World!";
195 * // 創(chuàng)建可以修改的字符串
196 * object Test{
197 * def main(args: Array[String]){
198 * val buf = new StringBuilder;
199 * buf += 'a' // 添加一個字符
200 * buf ++= "bcdef" // 添加一個字符串
201 * println(buf.toString); // 輸出:abcdef
202 * }
203 * }
204 *
205 * 字符串長度:xxx.length()
206 *
207 * 字符串連接:可以用concat()方法或者用加號
208 * object Test {
209 def main(args: Array[String]) {
210 var str1 = "字符串1:";
211 var str2 = "字符串2";
212 var str3 = "字符串3:";
213 var str4 = "字符串4";
214 println( str1 + str2 ); // 字符串1:字符串2
215 println( str3.concat(str4) ); // 字符串3:字符串4
216 }
217 }
218 *
219 * 創(chuàng)建格式化字符串:
220 * String類中可以使用printf()方法來格式化字符串并輸出。
221 * object Test{
222 * def main(args:Array[String]){
223 * var floatVar = 12.456
224 * var intVar = 2000
225 * var stringVar = "字符串變量"
226 * var fs = printf("浮點型變量為 " +
227 * "%f,整形變量為 %d, 字符串為 " +
228 * "%s", floatVar, intVar, stringVar)
229 * println(fs) // 浮點型變量為 12.456000, 整型變量為 2000, 字符串為 字符串變量
230 * }
231 * }
232 */
233
234 /**
235 * Scala數(shù)組:
236 * 1、聲明數(shù)組
237 * var z:Array[String] = new Array[String](3) 或者 var z = new Array[String]()
238 * z(0) = "value1"; z(1) = "value2"; z(2) = "value3"
239 *
240 * var z = Array("value1", "value2", "value3")
241 *
242 * 2、處理數(shù)組
243 * object Test{
244 * def main(args: Array[String]){
245 * var myList = Array(1.1, 2.2, 3.3, 4.4)
246 *
247 * // 輸出所有數(shù)組元素
248 * for(x <- myList){
249 * println(x)
250 * }
251 *
252 * // 計算數(shù)組所有元素的總和
253 * var total = 0.0
254 * for(i <- 0 to (myList.length - 1)){
255 * total += myList(i)
256 * }
257 * println("總和:" + total)
258 *
259 * // 查找數(shù)組中的最大元素
260 * var max = myList(0)
261 * for(i <- 1 to (myList.length - 1)){
262 * if(myList(i) > max)
263 * max = myList(i)
264 * }
265 * println("最大值:" + max)
266 * }
267 * }
268 *
269 * 3、多維數(shù)組
270 * import Array._
271 * object Test{
272 * def main(args: Array[String]){
273 * // 定義數(shù)組
274 * var myMatrix = ofDim[Int](3,3)
275 * // 創(chuàng)建矩陣
276 * for(i <- 0 to 2){
277 * for(j <- 0 to 2){
278 * myMatrix(i)(j) = j;
279 * }
280 * }
281 * // 打印矩陣
282 * for(i <- 0 to 2){
283 * for(j <- 0 to 2){
284 * print(" " + myMatrix(i)(j));
285 * }
286 * println();
287 * }
288 * }
289 * }
290 *
291 * 4、合并數(shù)組
292 * import Array._
293 * object Test{
294 * def main(args: Array[String]){
295 * var myList1 = Array(1.1, 2.2, 3.3, 4.4)
296 * var myList2 = Array(5.5, 6.6, 7.7, 8.8)
297 * // 使用concat()合并
298 * var myList3 = concat(myList1, myList2)
299 * // 輸出所有數(shù)組元素
300 * for(x <- myList3){
301 * println(x)
302 * }
303 * }
304 * }
305 *
306 * 5、創(chuàng)建區(qū)間數(shù)組:使用range(x,y,z)創(chuàng)建區(qū)間數(shù)組,數(shù)值范圍大于等于x,小于y。z表示步長,默認為1。
307 * object Test{
308 * def main(args: Array[String]){
309 * var myList1 = range(10, 20, 2)
310 * var myList2 = range(10, 20)
311 * for(x <- myList1){
312 * print(" " + x) //輸出:10 12 14 16 18
313 * }
314 * println()
315 * for(x <- myList2){
316 * print(" " + x) // 輸出:10 11 12 13 14 15 16 17 18 19
317 * }
318 * }
319 * }
320 */
321
322 /**
323 * Scala集合:分為可變集合和不可變集合。
324 * 可變集合:可以在適當(dāng)?shù)牡胤奖桓禄驍U展,也就是可以修改、添加、移除一個集合的元素。
325 * 不可變集合:永遠不會改變。但可以模擬添加、移除、更新操作,但是這些操作將在每一種情況下都返回一個新的集合,
326 * 同時使原來的集合不發(fā)生改變。
327 * // 定義整形List
328 * val x = List(1,2,3,4)
329 * // 定義Set
330 * var x = Set(1,3,5,7)
331 * // 定義Map
332 * val x = Map("one" -> 1, "two" -> 2, "three" -> 3)
333 * // 創(chuàng)建兩個不同類型的元組
334 * val x = (10, "Runoob")
335 * // 定義Option
336 * val x:Option[Int] = Some(5)
337 */
338
339 /**
340 * Scala迭代器:
341 * 迭代器不是一個集合,而是一個用于訪問集合的方法。
342 *
343 */
344 /*object Test{
345 def main(args: Array[String]): Unit = {
346 val it = Iterator("one", "two", "three", "four")
347 while(it.hasNext){ // 檢測集合中是否還有元素
348 println(it.next()) // 返回迭代器的下一個元素,并更新迭代器的狀態(tài)
349 }
350
351 val ita = Iterator(1, 2, 3, 4, 5)
352 val itb = Iterator(11, 22, 33, 44, 55)
353 //println(ita.max) // 查找最大元素
354 //println(itb.min) // 查找最小元素
355
356 println(ita.size) // 獲取迭代器的長度
357 println(itb.length) // 獲取迭代器的長度
358 }
359 }*/
360
361 /**
362 * Scala類和對象:
363 * 類是對象的抽象,對象是類的具體實例。
364 * 類是抽象的,不占用內(nèi)存;對象是類的具體實例,占用存儲空間。
365 *
366 */
367 /*import java.io._
368 class Point(xc: Int, yc: Int){
369 var x: Int = xc
370 var y: Int = yc
371 def move(dx: Int, dy: Int): Unit ={
372 x = x + dx
373 y = y + dy
374 println("x點的坐標是:" + x)
375 println("y點的坐標是:" + y)
376 }
377 }
378 object Test{
379 def main(args: Array[String]): Unit = {
380 val pt = new Point(10, 20)
381 // 移到一個新的位置
382 pt.move(10, 10)
383 }
384 }*/
385 /**
386 * Scala繼承:跟Java差不多。
387 * 1、重寫一個非抽象方法必須使用override修飾符
388 * 2、只有主構(gòu)造函數(shù)才可以往基類的構(gòu)造函數(shù)里寫參數(shù)
389 * 3、在子類中重寫超類的抽象方法時,不需要使用override
390 */
391 /*class Point(val xc: Int, val yc: Int){
392 var x: Int = xc
393 var y: Int = yc
394 def move(dx: Int, dy: Int): Unit ={
395 x = x + dx
396 y = y + dy
397 println("x點的坐標是:" + x)
398 println("y點的坐標是:" + y)
399 }
400 //-------------------------------------
401 var name = ""
402 override def toString = getClass.getName + "[name=" + name + "]"
403 }
404 class Location(override val xc: Int, override val yc: Int,
405 val zc: Int) extends Point(xc, yc){ // 繼承 重寫了父類的字段
406 var z: Int = zc
407 def move(dx: Int, dy: Int, dz: Int){
408 x = x + dx
409 y = y + dy
410 z = z + dz
411 println("x點的坐標是:" + x)
412 println("y點的坐標是:" + y)
413 println("z點的坐標是:" + z)
414 }
415 //---------------------------------------
416 var salary = 0.0
417 override def toString = super.toString + "[salary=" + salary + "]"
418 }
419 object Test{
420 def main(args: Array[String]): Unit = {
421 val loc = new Location(10, 20, 30)
422 loc.move(10, 10 ,5)
423 //------------------------------------
424 loc.name = "lc"
425 loc.salary = 35000.0
426 println(loc)
427 }
428 }*/
429
430 /**
431 * Scala單例對象:
432 * Scala中沒有static,要使用object關(guān)鍵字實現(xiàn)單例模式。
433 * Scala中使用單例模式時,除了定義類,還要定義一個同名的object對象,它和類的區(qū)別是,object對象不能帶參數(shù)。
434 * 當(dāng)單例對象與某個類共享一個名稱時,他被稱作這個類的伴生對象。
435 * 必須在同一個源文件里定義類和它的伴生對象。
436 * 類和它的伴生對象可以互相訪問其私有成員。
437 */
438 /*// 私有構(gòu)造方法
439 class Marker private(val color:String) {
440 println("創(chuàng)建" + this)
441 override def toString(): String = "顏色標記:"+ color //4:顏色標記:red
442 }
443
444 // 伴生對象,與類共享名字,可以訪問類的私有屬性和方法
445 object Marker{
446 private val markers: Map[String, Marker] = Map(
447 "red" -> new Marker("red"), //1:創(chuàng)建顏色標記:red
448 "blue" -> new Marker("blue"), //2:創(chuàng)建顏色標記:blue
449 "green" -> new Marker("green") //3:創(chuàng)建顏色標記:green
450 )
451
452 def apply(color:String) = {
453 if(markers.contains(color)) markers(color) else null
454 }
455
456 def getMarker(color:String) = {
457 if(markers.contains(color)) markers(color) else null //5:顏色標記:blue
458 }
459
460 def main(args: Array[String]) {
461 println(Marker("red"))
462 // 單例函數(shù)調(diào)用,省略了.(點)符號
463 println(Marker getMarker "blue")
464 }
465 }*/
466
467 /**
468 * Scala Trait(特征):
469 * 相當(dāng)于Java的接口,但比接口功能強大,它還可以定義屬性和方法的實現(xiàn)。
470 * 一般情況下Scala的類只能單繼承,但特征可以實現(xiàn)多重繼承。
471 */
472 /*// 定義特征
473 trait Equal{
474 def isEqual(x: Any): Boolean // 未實現(xiàn)的方法
475 def isNotEqual(x: Any): Boolean = !isEqual(x) // 實現(xiàn)了的方法
476 }
477
478 class Point(xc: Int, yc: Int) extends Equal{
479 var x: Int = xc
480 var y: Int = yc
481
482 override def isEqual(obj: Any): Boolean =
483 obj.isInstanceOf[Point] &&
484 obj.asInstanceOf[Point].x == x
485 }
486
487 object Test{
488 def main(args: Array[String]): Unit = {
489 val p1 = new Point(2, 3)
490 val p2 = new Point(2, 4)
491 val p3 = new Point(3, 3)
492 println(p1.isNotEqual(p2))
493 println(p1.isNotEqual(p3))
494 println(p1.isNotEqual(2))
495 }
496 }*/
497
498 /**
499 * 特征構(gòu)造順序:
500 * 構(gòu)造器的執(zhí)行順序:
501 * 1、調(diào)用超類的構(gòu)造器
502 * 2、特征構(gòu)造器在超類構(gòu)造器之后、類構(gòu)造器之前執(zhí)行
503 * 3、特征由左到右被構(gòu)造
504 * 4、每個特征當(dāng)中,父特征先被構(gòu)造
505 * 5、如果多個特征共有一個父特征,父特征不會被重復(fù)構(gòu)造
506 * 6、所有特征被構(gòu)造完畢,子類被構(gòu)造
507 */
508
509 /**
510 * Scala模式匹配:
511 * 選擇器 match {備選項}
512 */
513 /*object Test{
514 def main(args: Array[String]): Unit = {
515 println(matchTest("two"))
516 println(matchTest("test"))
517 println(matchTest(1))
518 println(matchTest(6))
519 }
520 def matchTest(x: Any): Any = x match {
521 case 1 => "one"
522 case "two" => 2
523 case y: Int => "scala.Int" // 對應(yīng)類型匹配
524 case _ => "many" // 默認全匹配選項
525 }
526 }*/
527 /**
528 * 使用樣例類:
529 * 使用case關(guān)鍵字的類定義就是樣例類,樣例類是種特殊的類,經(jīng)過優(yōu)化以用于模式匹配。
530 */
531 /*object Test{
532 def main(args: Array[String]): Unit = {
533 val alice = new Person("Alice", 25)
534 val bob = new Person("Bob", 32)
535 val charlie = new Person("Charlie", 27)
536 for(person <- List(alice, bob, charlie)){
537 person match{
538 case Person("Alice", 25) => println("Hi Alice!")
539 case Person("Bob", 32) => println("Hi Bob!")
540 case Person(name, age) => println("Age: " + age + " year,name: " + name +"?")
541 }
542 }
543 }
544 // 樣例類
545 case class Person(name: String, age: Int)
546 }*/
547
548 /**
549 * Scala正則表達式:
550 * 和Java差不多,在用的時候查一下就行了。
551 */
552
553 /**
554 * Scala異常處理:
555 * 和Java類似。在Scala中借用了模式匹配的方法來在catch語句塊中來進行異常匹配。
556 */
557 /*import java.io.{FileNotFoundException, FileReader, IOException}
558 object Test{
559 def main(args: Array[String]): Unit = {
560 try {
561 val f = new FileReader("input.txt")
562 }catch {
563 case ex: FileNotFoundException => {
564 println("Missing file exception")
565 }
566 case ex: IOException => {
567 println("IO Exception")
568 }
569 }finally {
570 println("Exiting finally...")
571 }
572 }
573 }*/
574
575 /**
576 * Scala提取器(Extractor):
577 * apply方法:無需new操作就可創(chuàng)建對象。
578 * unapply方法:是apply方法的反向操作,接受一個對象,然后從對象中提取值,提取的值通常是用來構(gòu)造對象的值。
579 */
580 /*object Test {
581 def main(args: Array[String]) {
582
583 println ("Apply 方法 : " + apply("Zara", "gmail.com")); // 也可直接Test("Zara", "gmail.com")來創(chuàng)建Zara@gmail.com
584 println ("Unapply 方法 : " + unapply("Zara@gmail.com"));
585 println ("Unapply 方法 : " + unapply("Zara Ali"));
586
587 }
588 // 注入方法 (可選)
589 def apply(user: String, domain: String) = {
590 user +"@"+ domain
591 }
592
593 // 提取方法(必選)
594 def unapply(str: String): Option[(String, String)] = {
595 val parts = str split "@"
596 if (parts.length == 2){
597 Some(parts(0), parts(1))
598 }else{
599 None
600 }
601 }
602 }*/
603 /**
604 * 提取器使用模式匹配:
605 * 在我們實例化一個類的時,可以帶上0個或者多個的參數(shù),編譯器在實例化的時會調(diào)用 apply 方法。
606 */
607 /*object Test {
608 def main(args: Array[String]) {
609
610 val x = Test(5)
611 println(x)
612
613 x match
614 {
615 case Test(num) => println(x + " 是 " + num + " 的兩倍!") //2:10是5的兩倍!
616 //unapply 被調(diào)用
617 case _ => println("無法計算")
618 }
619
620 }
621 def apply(x: Int) = x*2 //1:10
622 def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
623 }*/
624
625 /**
626 * Scala文件I/O:
627 *
628 */
629 /*// 文件寫操作
630 import java.io._
631 object Test {
632 def main(args: Array[String]) {
633 val writer = new PrintWriter(new File("test.txt" ))
634
635 writer.write("Scala語言")
636 writer.close()
637 }
638 }*/
639 // 從屏幕上讀取用戶輸入
640 /*object Test {
641 def main(args: Array[String]) {
642 print("請輸入菜鳥教程官網(wǎng) : " )
643 val line = Console.readLine // 在控制臺手動輸入
644
645 println("謝謝,你輸入的是: " + line)
646 }
647 }*/
648 // 從文件上讀取內(nèi)容
649 /*import scala.io.Source
650 object Test {
651 def main(args: Array[String]) {
652 println("文件內(nèi)容為:" )
653
654 Source.fromFile("test.txt" ).foreach{
655 print
656 }
657 }
658 }*/
|