《chang哥教你一天搞定Scala》
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 * 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数据类型: 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 = 0166 * sum = a + b167 * return sum168 * }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 = 3186 * muliplier(2) value = 6187 */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); // 输出:abcdef202 * }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:字符串2215 println( str3.concat(str4) ); // 字符串3:字符串4216 }217 }218 *219 * 创建格式化字符串:220 * String类中可以使用printf()方法来格式化字符串并输出。221 * object Test{222 * def main(args:Array[String]){223 * var floatVar = 12.456224 * var intVar = 2000225 * 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 * 1、声明数组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、处理数组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.0254 * 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 * 3、多维数组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 * 4、合并数组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 * 5、创建区间数组:使用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 18313 * }314 * println()315 * for(x <- myList2){316 * print(" " + x) // 输出:10 11 12 13 14 15 16 17 18 19317 * }318 * }319 * }320 */321 322 /**323 * Scala集合:分为可变集合和不可变集合。324 * 可变集合:可以在适当的地方被更新或扩展,也就是可以修改、添加、移除一个集合的元素。325 * 不可变集合:永远不会改变。但可以模拟添加、移除、更新操作,但是这些操作将在每一种情况下都返回一个新的集合,326 * 同时使原来的集合不发生改变。327 * // 定义整形List328 * val x = List(1,2,3,4)329 * // 定义Set330 * var x = Set(1,3,5,7)331 * // 定义Map332 * val x = Map("one" -> 1, "two" -> 2, "three" -> 3)333 * // 创建两个不同类型的元组334 * val x = (10, "Runoob")335 * // 定义Option336 * 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 = xc370 var y: Int = yc371 def move(dx: Int, dy: Int): Unit ={372 x = x + dx373 y = y + dy374 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、只有主构造函数才可以往基类的构造函数里写参数389 * 3、在子类中重写超类的抽象方法时,不需要使用override390 */391 /*class Point(val xc: Int, val yc: Int){392 var x: Int = xc393 var y: Int = yc394 def move(dx: Int, dy: Int): Unit ={395 x = x + dx396 y = y + dy397 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 = zc407 def move(dx: Int, dy: Int, dz: Int){408 x = x + dx409 y = y + dy410 z = z + dz411 println("x点的坐标是:" + x)412 println("y点的坐标是:" + y)413 println("z点的坐标是:" + z)414 }415 //---------------------------------------416 var salary = 0.0417 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.0426 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:颜色标记:red442 }443 444 // 伴生对象,与类共享名字,可以访问类的私有属性和方法445 object Marker{446 private val markers: Map[String, Marker] = Map(447 "red" -> new Marker("red"), //1:创建颜色标记:red448 "blue" -> new Marker("blue"), //2:创建颜色标记:blue449 "green" -> new Marker("green") //3:创建颜色标记:green450 )451 452 def apply(color:String) = {453 if(markers.contains(color)) markers(color) else null454 }455 456 def getMarker(color:String) = {457 if(markers.contains(color)) markers(color) else null //5:颜色标记:blue458 }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 = xc480 var y: Int = yc481 482 override def isEqual(obj: Any): Boolean =483 obj.isInstanceOf[Point] &&484 obj.asInstanceOf[Point].x == x485 }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 * 1、调用超类的构造器502 * 2、特征构造器在超类构造器之后、类构造器之前执行503 * 3、特征由左到右被构造504 * 4、每个特征当中,父特征先被构造505 * 5、如果多个特征共有一个父特征,父特征不会被重复构造506 * 6、所有特征被构造完毕,子类被构造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" => 2523 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.com584 println ("Unapply 方法 : " + unapply("Zara@gmail.com"));585 println ("Unapply 方法 : " + unapply("Zara Ali"));586 587 }588 // 注入方法 (可选)589 def apply(user: String, domain: String) = {590 user +"@"+ domain591 }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 None600 }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 match614 {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:10622 def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None623 }*/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.Source650 object Test {651 def main(args: Array[String]) {652 println("文件内容为:" )653 654 Source.fromFile("test.txt" ).foreach{655 print656 }657 }658 }*/