《chang哥教你一天搞定Scala》java
1 /** 2 * 《chang哥教你一天搞定Scala》 3 * scala是一門多範式編程語言,集成了面向對象編程和函數式編程等多種特性。 4 * scala運行在虛擬機上,併兼容現有的Java程序。 5 * Scala源代碼被編譯成java字節碼,因此運行在JVM上,並能夠調用現有的Java類庫。 6 */ 7 8 /** 9 * 第一個Scala程序 10 * Scala和Java最大的區別是:Scala語句末尾的分號(;)是可選的! 11 * 編譯運行: 12 * 先編譯:scalac HelloScala.scala 將會生成兩個文件:HelloScala$.class和HelloScala.class 13 * 在運行:scala HelloScala 14 * 輸出結果: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 * 區分大小寫 26 * 類名首字母大寫(MyFirstScalaClass) 27 * 方法名稱第一個字母小寫(myMethodName()) 28 * 程序文件名應該與對象名稱徹底匹配 29 * def main(args:Array[String]):scala程序從main方法開始處理,程序的入口。 30 * 31 * Scala註釋:分爲多行/**/和單行// 32 * 33 * 換行符:Scala是面向行的語言,語句能夠用分號(;)結束或換行符(println()) 34 * 35 * 定義包有兩種方法: 36 * 一、package com.ahu 37 * class HelloScala 38 * 二、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數據類型: 53 * Scala與Java有着相同的數據類型,下面列出一些Scala有的數據類型。 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中,使用關鍵字「var」聲明變量,使用關鍵字「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關鍵字修飾的成員僅在包含了成員定義的類或對象內部可見。 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中,訪問修飾符能夠經過使用限定詞強調。 117 * private[x] 或者 protected[x] 118 * private[x]:這個成員除了對[...]中的類或[...]中的包中的類及他們的伴生對象可見外,對其餘的類都是private。 119 */ 120 121 /** 122 * Scala運算符:和Java同樣,這裏就再也不浪費時間一一介紹了。 123 * 算術運算符、關係運算符、邏輯運算符、位運算符、賦值運算符。 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循環:和Java同樣,這裏不贅述,只介紹三種循環類型。 155 * while循環、do...while循環、for循環 156 */ 157 158 /** 159 * Scala函數:用一個例子來講明函數的定義和函數調用。 160 * object Test{ 161 * def main(args: Array[String]){ 162 * println(addInt(1,3)); // 函數調用 163 * } 164 * def addInt(a:Int, b:Int) : Int = { // 函數定義 165 * var sum:Int = 0 166 * sum = a + b 167 * return sum 168 * } 169 * } 170 */ 171 172 /** 173 * Scala閉包: 174 * 閉包是一個函數,返回值依賴於聲明在函數外部的一個或多個變量。 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 // 定義在函數外的自由變量 182 * val muliplier = (i:Int) => i * factor // muliplier函數變量就是一個閉包 183 * } 184 * 輸出結果: 185 * muliplier(1) value = 3 186 * muliplier(2) value = 6 187 */ 188 189 /** 190 * Scala字符串: 191 * 192 * Scala中能夠建立兩中字符串:一種是不可修改的,一種是能夠修改的。 193 * // 建立不可修改的字符串 194 * val greeting:String = "Hello World!"; 195 * // 建立能夠修改的字符串 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 * 建立格式化字符串: 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數組: 236 * 一、聲明數組 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 * 二、處理數組 243 * object Test{ 244 * def main(args: Array[String]){ 245 * var myList = Array(1.1, 2.2, 3.3, 4.4) 246 * 247 * // 輸出全部數組元素 248 * for(x <- myList){ 249 * println(x) 250 * } 251 * 252 * // 計算數組全部元素的總和 253 * var total = 0.0 254 * for(i <- 0 to (myList.length - 1)){ 255 * total += myList(i) 256 * } 257 * println("總和:" + total) 258 * 259 * // 查找數組中的最大元素 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 * 三、多維數組 270 * import Array._ 271 * object Test{ 272 * def main(args: Array[String]){ 273 * // 定義數組 274 * var myMatrix = ofDim[Int](3,3) 275 * // 建立矩陣 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 * 四、合併數組 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 * // 輸出全部數組元素 300 * for(x <- myList3){ 301 * println(x) 302 * } 303 * } 304 * } 305 * 306 * 五、建立區間數組:使用range(x,y,z)建立區間數組,數值範圍大於等於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 * 可變集合:能夠在適當的地方被更新或擴展,也就是能夠修改、添加、移除一個集合的元素。 325 * 不可變集合:永遠不會改變。但能夠模擬添加、移除、更新操做,可是這些操做將在每一種狀況下都返回一個新的集合, 326 * 同時使原來的集合不發生改變。 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 * // 建立兩個不一樣類型的元組 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()) // 返回迭代器的下一個元素,並更新迭代器的狀態 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 * 類是抽象的,不佔用內存;對象是類的具體實例,佔用存儲空間。 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 * 一、重寫一個非抽象方法必須使用override修飾符 388 * 二、只有主構造函數才能夠往基類的構造函數裏寫參數 389 * 三、在子類中重寫超類的抽象方法時,不須要使用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關鍵字實現單例模式。 433 * Scala中使用單例模式時,除了定義類,還要定義一個同名的object對象,它和類的區別是,object對象不能帶參數。 434 * 當單例對象與某個類共享一個名稱時,他被稱做這個類的伴生對象。 435 * 必須在同一個源文件裏定義類和它的伴生對象。 436 * 類和它的伴生對象能夠互相訪問其私有成員。 437 */ 438 /*// 私有構造方法 439 class Marker private(val color:String) { 440 println("建立" + 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:建立顏色標記:red 448 "blue" -> new Marker("blue"), //2:建立顏色標記:blue 449 "green" -> new Marker("green") //3:建立顏色標記: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 // 單例函數調用,省略了.(點)符號 463 println(Marker getMarker "blue") 464 } 465 }*/ 466 467 /** 468 * Scala Trait(特徵): 469 * 至關於Java的接口,但比接口功能強大,它還能夠定義屬性和方法的實現。 470 * 通常狀況下Scala的類只能單繼承,但特徵能夠實現多重繼承。 471 */ 472 /*// 定義特徵 473 trait Equal{ 474 def isEqual(x: Any): Boolean // 未實現的方法 475 def isNotEqual(x: Any): Boolean = !isEqual(x) // 實現了的方法 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 * 特徵構造順序: 500 * 構造器的執行順序: 501 * 一、調用超類的構造器 502 * 二、特徵構造器在超類構造器以後、類構造器以前執行 503 * 三、特徵由左到右被構造 504 * 四、每一個特徵當中,父特徵先被構造 505 * 五、若是多個特徵共有一個父特徵,父特徵不會被重複構造 506 * 六、全部特徵被構造完畢,子類被構造 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" // 對應類型匹配 524 case _ => "many" // 默認全匹配選項 525 } 526 }*/ 527 /** 528 * 使用樣例類: 529 * 使用case關鍵字的類定義就是樣例類,樣例類是種特殊的類,通過優化以用於模式匹配。 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操做就可建立對象。 578 * unapply方法:是apply方法的反向操做,接受一個對象,而後從對象中提取值,提取的值一般是用來構造對象的值。 579 */ 580 /*object Test { 581 def main(args: Array[String]) { 582 583 println ("Apply 方法 : " + apply("Zara", "gmail.com")); // 也可直接Test("Zara", "gmail.com")來建立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個或者多個的參數,編譯器在實例化的時會調用 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 被調用 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("請輸入菜鳥教程官網 : " ) 643 val line = Console.readLine // 在控制檯手動輸入 644 645 println("謝謝,你輸入的是: " + line) 646 } 647 }*/ 648 // 從文件上讀取內容 649 /*import scala.io.Source 650 object Test { 651 def main(args: Array[String]) { 652 println("文件內容爲:" ) 653 654 Source.fromFile("test.txt" ).foreach{ 655 print 656 } 657 } 658 }*/