大数据最火爆语言Scala光速入门-笔记

nbj 贡献于2016-01-14

作者 ning  创建于2016-01-14 01:37:00   修改者ning  修改于2016-01-14 01:37:00字数6135

文档摘要:scala介绍Scala完全面向对象相对于Java而言,Scala的代码更为精简(减低犯错),而且功能更为广泛(Scala其实是ScalableLanguage的简称,意为可扩展的语言),许多Scala的特性和语法都是针对Java的不足和弱点来设计的。Scala的特点是有很多函数程式语言的特性(例如ML,Miranda,Scheme,Haskell),譬如惰性求值,listcomprehension,typeinference,anonymousfunction,patternmatching等等,同时也包含Object-Oriented的特性(OO能与FP混合使用是Scala的亮点)。此外,许多相似于高级编程语言的语法也渗入其中(例如Python),不仅提高了Scala代码的可读性,维护、修改起来也较为省时省力。Scala与Java语法上的明显差异有:不需要分号结尾类型定义开头需大写(与Haskell相同)函数定义需 def 开头(与Python、Ruby相同)return 可以省略scala安装解压设置PATH即可,前提是需要先安装JDK,不在过多描述。
关键词:

一、 scala介绍 Scala完全面向对象 相对于Java而言,Scala的代码更为精简(减低犯错),而且功能更为广泛(Scala其实是Scalable Language 的简称,意为可扩展的语言),许多Scala的特性和语法都是针对Java的不足和弱点来设计的。Scala的特点是有很多函数程式语言的特性(例如ML,Miranda, Scheme,Haskell),譬如惰性求值,list comprehension, type inference, anonymous function, pattern matching 等等,同时也包含 Object-Oriented 的特性(OO 能与 FP 混合使用是 Scala 的亮点)。此外,许多相似于高级编程语言的语法也渗入其中(例如 Python),不仅提高了 Scala 代码的可读性,维护、修改起来也较为省时省力。 Scala 与 Java 语法上的明显差异有: l 不需要分号结尾 l 类型定义开头需大写(与 Haskell 相同) l 函数定义需 def 开头(与 Python、Ruby 相同) l return 可以省略 二、 scala安装 解压设置PATH即可,前提是需要先安装JDK,不在过多描述。 三、 scala快速入门 //简单测试 scala> 1+2 res1: Int = 3 scala> 1.5*2 res2: Double = 3.0 scala> res2*3 res3: Double = 9.0 //命令行tab键进行代码提示 scala> res2.to toByte toChar toDouble toFloat toInt toLong toShort toString //变量引用转换 scala> res3.toInt res4: Int = 9 //val 不可变类型 scala> val result = 2 + 10 result: Int = 12 //var 可变类型 scala> var name = "spark" name: String = spark scala> name="SCALA" name: String = SCALA //指定具体变量类型 scala> val age:Int = 13 age: Int = 13 //以后只能给name赋值string类型 scala> var name :String = null name: String = null //声明多个变量 scala> val age1,age2,age3 = 0 age1: Int = 0 age2: Int = 0 age3: Int = 0 //一切皆对象 数字0也是一个对象 能调用方法 scala> 0.to(5) res5: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, 4, 5) //1+1调用的也是方法+ scala> 1+1 res6: Int = 2 scala> 1.+(1) warning: there were 1 deprecation warning(s); re-run with -deprecation for details res7: Double = 2.0 //scala 没有++ -- //调用函数 scala> import scala.math._ import scala.math._ scala> min(2,4) res8: Int = 2 //实例构造 调用的是apply方法 scala> val arr = Array(1,2,3) arr: Array[Int] = Array(1, 2, 3) scala> val arr=Array.apply(1,2,3) arr: Array[Int] = Array(1, 2, 3) //if表达式 可以有返回值 scala> val age = 19 age: Int = 19 scala> if(age>18)"adult" else "child" res9: String = adult //块表达式最后一行是块的返回值 //打印 scala> println("spark") spark scala> print("\nspark") spark scala> printf("%s is the future \n","spark") spark is the future 四、 scala函数简单入门 1. 函数声明 def functionName ([list of parameters]) : [return type] 2. 函数定义: def functionName ([list of parameters]) : [return type] = { function body return [expr] } 返回类型可以是任何有效的scala数据类型。它不返回任何东西,可以返回这相当于在Java中void,并表示该函数不返回任何单元。Scala中不返回任何东西函数被称为过程。以下是语法 object Hello{ def printMe( ) : Unit = { println("Hello, Scala!") } } 3. 调用函数 object Test { def main(args: Array[String]) { println( "Returned Value : " + addInt(5,7) ); } def addInt( a:Int, b:Int ) : Int = { var sum:Int = 0 sum = a + b return sum } } 4. 命名参数 object Test { def main(args: Array[String]) { printInt(b=5, a=7); } def printInt( a:Int, b:Int ) = { println("Value of a : " + a ); println("Value of b : " + b ); } } 5. 可变参数 object Test { def main(args: Array[String]) { printStrings("Hello", "Scala", "Python"); } //*表示可以传入多个参数 def printStrings( args:String* ) = { var i : Int = 0; for( arg <- args ){ println("Arg value[" + i + "] = " + arg ); i = i + 1; } } } 6. 默认参数值 object Test { def main(args: Array[String]) { println( "Returned Value : " + addInt() ); } //参数默认值 a 5 b 7 def addInt( a:Int=5, b:Int=7 ) : Int = { var sum:Int = 0 sum = a + b return sum } } 五、 scala数组 数组是定义数据类型很重要很基础的容器 1. 不可变数组 val greetStrings = new Array[String](3) //赋值  greetStrings(0) = "Hello"  greetStrings(1) = ", "  greetStrings(2) = "world!\n"  //遍历数组 for (i <- 0 to 2)   print(greetStrings(i))   Array[String]表示类型,可以读成字符串的数组,它是一个类型,也就是类,所以可以用new去实例化。括号3表示数组容量是3 数组元素赋值 greetStrings(0) = "Hello"   虽然greetStrings是不可更改的,但数字元素可以。 Scala用小括号代替java的中括号,可能很多java工程师会说:呵,发明新轮子。 其实Scala是被冤枉的。 Scala里所以东西都是对象,数组也不例外。数组赋值其实也是一个方法完成的。 上面的代码会被编译器转换成两个参数的方法: greetStrings.update(0, "Hello") 数组元素读取 print(greetStrings(i))   为什么Scala不用中括号呢?是因为Scala有一套通用规则,会把小括号转换成apply。所以编译器会得到这样的代码: print(greetStrings.apply(i))    如果不使用符号,我们的代码同样可以完成: val greetStrings = new Array[String](3)     greetStrings.update(0, "Hello")     greetStrings.update(1, ", ")     greetStrings.update(2, "world!\n")     for (i <- 0.to(2))     print(greetStrings.apply(i))    for (i <- 0.to(2))可以写成for (i <- 0 to 2)    2. 可变数组ArrayBuffer val ab = scala.collection.mutable.ArrayBuffer[Int](); // 尾部添加一个元素 ab +=1 //尾部添加整个数组的元素 ab += 1ab ++=Array(2,3,4,5,6) //下标为2的位置添加元素100 ab.insert(2,100) //裁剪[删除]开始两个元素 ab.trimStart(2) //删除结尾两个元素 ab.trimEnd(2) //删除下标为5的元素 ab.remove(3) //从下标为3的位置开始删除,总共删除2两个元素 ab.remove(3,3) //转换为不可变数组 ab.toArray //遍历 ,1表示打印间隔为1个元素,就是所有元素都打印 for( i <- 0 until (ab.length,1))println(ab(i)) //遍历 ,2表示打印间隔为2个元素,每隔一个元素打印 for( i <- 0 until (ab.length,2))println(ab(i)) //尾部进行遍历 for(i <- (0 until ab.length).reverse) println(ab(i)) //快速排序 scala> val abArr = ab.toArray abArr: Array[Int] = Array(100, 3, 4, 6) scala> scala.util.Sorting.quickSort(abArr) scala> abArr res21: Array[Int] = Array(3, 4, 6, 100) //filter map方法 //filter表示过滤符合条件的元素 //map表示对集合的所有元素进行同样的操作 //提取符合3的倍数的元素,进行平方 val r = abArr.filter(_%3==0).map(i=>i*i) 六、 Map基本操作 //定义一个可变map val m = scala.collection.mutable.Map("spark"->6,"hadoop"->10) //添加kv m +=("java"->11) //删除元素 m -=("java") //获取key对应的value val v = if(m.contains("spark")) m("spark") else 10000 val v = m.getOrElse("spark",100001) //遍历k v for((k,v) <-m)println("k="+k+",v="+v) //定义 一个排序的map scala> val m = scala.collection.immutable.SortedMap("spark"->1,"hadoop"->2) m: scala.collection.immutable.SortedMap[String,Int] = Map(hadoop -> 2, spark -> 1) 七、 tuple基本操作 tuple。与列表一样,元组也是不可变的,但与列表不同,元组可以包含不同类型的元素.元组可以同时拥有Int和String。元组很有用,比方说,如果你需要在方法里返回多个对象 val pair = (99, "Luftballons")   println(pair._1)   println(pair._2)   八、 lazy关键字 lazy表示延迟执行,只有真正使用的时候才会执行。scala 中只有 val 才允许 lazy。所以不能用泛型. 九、 循环 while Scala中使用while和java差不多。 var i = 0  while (i < args.length) {   println(args(i))   i += 1  }  注意,Scala中不能用i++或++i Scala也有do-while循环 var line = ""  do {    line = readLine()    println("Read: " + line)   } while (line != null)   for进行迭代 for做的最简单的事情就是把一个集合类的所有元素都枚举一遍 val filesHere = (new java.io.File(".")).listFiles for (file < - filesHere) println(file) for表达式语法对任何种类的集合类都有效,而不只是数组。更精确地说,在<-符号右侧的表达式必须支持名为foreach的方法 1. for (i < - 1 to 4) 2. println("Iteration " + i) 不想包括被枚举的Range的上边界,可以用until替代to: 过滤 有些时候你不想枚举一个集合类的全部元素。而是想过滤出一个子集。你可以通过把过滤器:filter:一个if子句加到for的括号里做到。如代码7.6的代码仅对当前目录中以“.scala”结尾的文件名做列表: val filesHere = (new java.io.File(".")).listFiles for (file < - filesHere if file.getName.endsWith(".scala")) println(file) //可以包含更多的过滤器 for ( file < - filesHere if file.isFile; if file.getName.endsWith(".scala") ) println(file) 如果在发生器中加入超过一个过滤器,if子句必须用分号分隔。这是代码中的“if file.isFile”过滤器之后带着分号的原因。 mid-stream(流间)变量绑定 def grep(pattern: String) = for { file < - filesHere if file.getName.endsWith(".scala") line < - fileLines(file) trimmed = line.trim if trimmed.matches(pattern) } println(file + ": " + trimmed) grep(".*gcd.*") 制造新集合 只要在for表达式之前加上关键字yield for表达式在每次执行的时候都会制造一个值,本例中是file。当for表达式完成的时候,结果将是一个包含了所有产生的值的集合。结果集合的类型基于枚举子句处理的集合类型。本例中结果为Array[File],因为filesHere是数组并且产生的表达式类型是File。 def scalaFiles = for { file < - filesHere if file.getName.endsWith(".scala") } yield file 十、 作业 1. 移除数组中第一个负数后的所有负数 //1. 移除数组中第一个负数后的所有负数 val arr = ArrayBuffer[Int](1,2,3,-1,-1,3,-1,4,-3,5,-4,9,0,-8,2) var j = 0 val newArr = arr.filter { i => val needFilter = (i<0&&j!=0) if(i < 0){ j = 1 } !needFilter } println(newArr)

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档