zoukankan      html  css  js  c++  java
  • 快学Scala第一部分

    转载:

    1、变量声明

    1. val answer = 8 * 5 + 2; //常量  
    2. var counter = 0;    //变量  
    3. //在必要的时候 ,可以指定类型  
    4. val greeting:String = null  
    5. val greeting:Any = "Hello"  
    6. //可以将多个值或变量放在一起声明  
    7. val xmax, ymax = 100 //xmax 和 ymax设为100  
    8. var greeting, message:String = null // 都被设为字符串,被初始化为null  
    在CODE上查看代码片派生到我的代码片
    1. 常用数值类型  
    2. Byte Char Short Int Long Float Double Boolean   
    3. BigInteger BigDecimal 用于任意大小的数字  
    scala的 StringOps, RichInt, RichDouble, RichChart 给基本类型提供了很多方法,在调用时会自动隐式转换
    1. "Hello".intersect("World")  //输出"lo"  
    2. 1.to(10) //Int值1首先被转换为RichInt,然后调用to方法  
    在CODE上查看代码片派生到我的代码片
    1. 不像java用 强制类型转换,而是用方法  
    2. 99.44.toInt         //99, 这里不带参数,并且不改变当前对象的方法 通常不实用圆括号  
    3. 99.toChart      //'c'  
    4. 99.toString         //"99"  
    5. "99.44".toDouble    // 99.44  

    在CODE上查看代码片派生到我的代码片
    1. "Hello"(4) // '0'  
    2. 实际上是StringOps类的apply方法  
    3. def apply(n:Int) : Char  
    4. "Hello".apply(4) // 完整写法  
    5.   
    6. BigInt伴生对象的apply方法:  
    7. BigInt("1234567890") // BigInt.apply("1234567890")  
    8.   
    9. BigInt("123") * BigInt("123")  
    10.   
    11. 数组Array,也是伴生对象  
    12. Array(1,4,9,16)   

    在CODE上查看代码片派生到我的代码片
    1. if (x > 0) else -1  
    2. 可以将if/else表达式的值赋给变量  
    3. val s = if(x > 0) else -1  
    4.   
    5. 每个表达式都有一个类型  
    6. if(x > 0) else -1  // Int  
    7. if(x > 0) "p" else -// Any (Int 和String的超类)  
    8. if(x > 0) 1   // (),Unit类,因为可能没有输出值,即if(x >0) 1 else ()  
    9.   
    10. while(n > 0){  
    11.   r = r*n  
    12.   n -=1  
    13. }  

    在CODE上查看代码片派生到我的代码片
    1. for( i <- 表达式)  
    2.   
    3. for( i <- 1 to 10)  
    4.   r = r*i  
    5.   
    6. val s = "Hello"  
    7. var sum = 0  
    8. for( i <- 0 until s.length)  
    9.   sum+= s(i)  
    10.   
    11. 简化版:  
    12. var sum = 0  
    13. for(ch <- "Hello") sum+=ch  

    在CODE上查看代码片派生到我的代码片
    1. for( i <- 1 to 3; j <- 1 to 3)  println((10 * i + j)+ "")  
    2. 11 12 13 21 22 23 31 32 33  
    3.   
    4. for(i <- 1 to 3; j <- 1 to if i != j)print((10 * i + j)+ "")  
    5. 12 13 21 23 31 32  
    6. 注意在if前没有分号  
    7.   
    8. for(i <- 3; from = 4 - i ; j <- from to 3) print((10 * i + j) + " ")  
    9.  31 22 23 31 32 33  
    10.   
    11. for( i <- 1 to 10) yield i % 3  
    12. 生成 Vector(1,2,0,1,2,0,1,2,0,1)  
    13.   
    14. 推导式生成的集合与第一个生成器是类型兼容的:  
    15. for( c<- "Hello"; i<- 0 to 1) yield (c + i).toChar  
    16. "Hilflmlmop"  
    17.   
    18. for(i <- 0 to 1; c <- "Hello") yield (c + i).toChar  
    19. Vector('H','e','l',''l','o','I','f','m','m','p')  

    在CODE上查看代码片派生到我的代码片
    1. def abs(x:Double) = if(x >=0) x else -x  
    2. def fac(n:Int) = {  
    3.   var r=1  
    4.   for( i<- 1 to n) r=r*i  
    5.   r // 无需return,最后一行即返回值  
    6. }  
    7.   
    8. 一般定义函数无需指定返回类型,Scala可以通过=符号右侧的表示式的类型推断返回类型,除非是递归函数。  
    9. def fac(n:Int) :Int = if(n<=0) else n* fac(n-1)// 如果没有返回类型,Scala无法校验 n*fac(n-1)的类型是Int  

    在CODE上查看代码片派生到我的代码片
    1. def decorate(str:String, left:String="[", right:String ="]") = left + str +right  
    2.   
    3. decorate("Hello", "<<<", ">>>")           // <<<Hello>>>  
    4. decorate("Hello","<<<")                // <<<Hello]  
    5. decorate(left = "<<<", str = "Hello" , right = ">>>")     // 指定参数名,<<<Hello>>>  
    6. decorate("Hello", right=">>>")             // 混用  

    在CODE上查看代码片派生到我的代码片
    1. def sum(args: Int*){  
    2.   var result = 0  
    3.   for (arg <- args) result += arg  
    4.   result  
    5. }  
    6. val s = sum(1,4,9,16,25)                //函数得到 类型Seq的参数  
    7.   
    8. val s = sum(1 to 5)                     // 错误  
    9. val s = sum(1 to 5: _*)                 //将 1 to 5当做参数序列处理  
    10.   
    11. 递归中使用  
    12. def recursiveSum(args : Int *): Int = {  
    13.   if (args.length ==0) 0  
    14.   else args.head + recursiveSum(args.tail:_*)       // head是首个元素, tail是所有其他元素的序列,是一个Seq  
    15. }  

    在CODE上查看代码片派生到我的代码片
    1. 过程不返回任何值,可以略去=号  
    2. def box(x:String) {  
    3.   println(x)  
    4. }  
    5. 也可以显式声明Unit返回类型  
    6. def box(x:String) :Unit = {}</span>  


    懒值

    1. lazy val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString //直到我们首次对它取值才会初始化。  
    2.   
    3. 可以把懒值当做介于 val和def的中间状态:  
    4. val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString//在words被定义时即被取值  
    5. lazy val words= scala.io.Source.fromFile("/usr/share/dict/words").mkString//在首次调用  
    6. def words= scala.io.Source.fromFile("/usr/share/dict/words").mkString//在每一次被使用时  

    异常
    1. if (x >= 0 )  { sqrt(x) }  
    2. else throw new IllegalArgumentException("x should not be negative")  
    3. throw 表达式有特殊的类型Nothing, 在if/else中,如果以个分支的类型为Nothing, 那么表达式的类型就是 另一个分支的类型, 在这里就是 Double  
    1. 捕获异常,使用模式匹配  
    2. try{  
    3.   
    4. }catch{  
    5.   case _: MalformedURLException => println("Bad Url:" + url)  
    6.   case ex: IOException => ex.printStackTrace()  
    7. }  
    8.   
    9. var in = new URL("http://xxx.com").openStream()  
    10. try{  
    11.   process(in)  
    12. }finally{  
    13.   in.close()  
    14. }  
    15. try{...} catch{...} finally{...}  

    3、数组

    1. 定长数组  
    2. val nums = new Array[Int](10)           // 都是0  
    3. val a = new Array[String](10)           // 都是null  
    4. val s = Array("Hello", "World")         // Array伴生对象的apply 方法  
    5. s(0) = "Goodbye"                //Array("Goodbye","World")  
    6.   
    7. 变长数组  
    8. import scala.collection.mutable.ArrayBuffer  
    9. val b = ArrayBuffer[Int]()          // 伴生对象的apply  
    10. //或者 new ArrayBuffer[Int]  
    11. b += 1                          //(1)  
    12. b += (1,2,3,5)                  // (1,1,2,3,5)  
    13. b ++= Array(8,13,21)                // 可以用++=追加任何集合 (1,1,2,3,5,8,13,21)  
    14. b.trimEnd(5)                    //移除最后5个元素 , (1,1,2)  
    15.   
    16. b.insert(2,6)                   // (1,1,6,2)  
    17. b.insert(2,7,8,9)               // (1,1,7,8,9,6,2)  
    18. b.remove(2)                     // (1,1,8,9,6,2)  
    19. b.remove(2,3)                   //(1,1,2)  
    20.   
    21. b.toArray                   // Array(1,1,2) ,变长转定长  
    22. a.toBuffer                  // 定长转变长  

    遍历数组
    1. for(i <- 0 until.a.length)  
    2.   println(i + ": " + a(i))  
    3.   
    4. 如果在循环体中不需要下表  
    5. for(elem <- a )  
    6.   println(elem)  

    数组转换
    1. val a = Array(2,3,5,7,11)  
    2. val result = for(elem <- a) yield 2 * elem  
    3. // result 是 Array(4, 6, 10 , 14, 22)  
    4.   
    5. for(elem <- a if elem %2 ==0) yield 2 * elem  
    6. 另一种做法  
    7. a.filter(_ % 2 ==2).map(2 * _)  
    1. 移除第一个负数之外的所有负数  
    2. 首先收集需要保留的下标:  
    3. var first = true  
    4. val indexs = for(i <-0 until a.length if first || a(i) >=0) yield {  
    5.   if(a(i)<0) first = false; i  // 按 书序记录了所有正数和第一个负数的小标,其他负数的小标都丢弃 了</span><pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;">} </span>  
    6. for(j <- 0 until.indexs.length) a(j) = a(index(j))//将元素移动到该去的位置 a.trimEnd(a.length - indexs.length)//并截断尾端//这里主要是 小标处理  

    常用算法
    1. Array(1,7,2,9).sum  <span style="white-space:pre">                    </span>//19  
    2. ArrayBuffer("Mary","had","a","little",'lamb').max   <span style="white-space:pre">    </span>//"little"  
    3.   
    4. val b = ArrayBuffer(1,7,2,9)  
    5. val bSorted = b.sorted(_ < _) <span style="white-space:pre">               </span>// (1,2,7,9) 这里b没有改变,可以提供一个比较函数,用sortWith方法  
    6.   
    7. val a = Array(1,7,2,9)  
    8. scala.util.Sorting.quickSort(a) <span style="white-space:pre">            </span>// 此方法不适于ArrayBuffer  
    9.   
    10. a.mkString(" and ") <span style="white-space:pre">                    </span>// "1 and 2 and 7 and 9"  
    11. a.mkString("<", "," , ">")<span style="white-space:pre">                </span>// "<1,2,7,9>"  

    多维数组
    1. Array[Array[Double]] , 也可以通过ofDim方法:  
    2. val matrix = Array.ofDim[Double](3,4) // 三行,四列  
    3. matrix(row)(col) = 42  
    4.   
    5. 创建不规则的多维数组  
    6. var triangle = new Array[Array[Int]](10)  
    7. for(i <- 0 until triangle.length)  
    8.   triangle(i) = new Array[Int](i+1)  

    与Java的互操作
    1. 通过引入scala.collection.JavaConversions里的隐式转换方法,可以自动包装成Java对象,如列表等。  
    2. import scala.collection.JavaConversions.bufferAsJavaList  
    3. import scala.collection.mutable.ArrayBuffer  
    4. val command = ArrayBuffer("ls", "-all" , "/home/clat")  
    5. val pb = new ProcessBuilder(command)   
    6. // Scala to Java, Scala缓冲数组被包装成一个实现了java.until.List接口的Java类的对象  
    7.   
    8. 反过来,把Java.until.List,自动转换成一个Buffer  
    9. import scala.collection.JavaConversions.asScalaBuffer  
    10. import scala.collection.mutable.Buffer  
    11. val cmd :Buffer[String] = pb.command()   
    12. // java to scala, 不能使用ArrayBuffer, 包装起来的对象仅能保证是个Buffer  

    4、映射和元素

    1. val scores = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8 )    //不可变Map[String, Int]  
    2.   
    3. val scores = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8 )    //可变Map[String, Int]  
    4.   
    5. val scores = new scala.collection.mutable.HashMap[String, Int]              //定义一个空的Map,需要给出类型参数  
    6.   
    7. Map 是对偶的集合, -> 操作符 用来创建对偶, "Alice" -> 10 产出的值是 ("Alice", 10)  
    8. 所以也可以用下面的方法定义 Map:  
    9. val scores = Map(("Alice",10),("Bob",3),("Cindy",8)) <span style="white-space:pre">               </span>//只不过 -> 操作符 比 圆括号 更易读,更符合大家对Map的直观感觉。  
    10. 获取Map中的值  
    11. val bobScore = scores("Bob") <span style="white-space:pre">                           </span>// 类似java的 scores.get("Bob"), 如果不存在,则抛出异常  
    12. val bobsScore = if(scores.contain("Bob")) scores("Bob") else 0 <span style="white-space:pre">         </span>// 可以用contains 来判断  
    13.   
    14. val bobsScore = scores.getOrElse("Bob",0) <span style="white-space:pre">                  </span>//便捷写法  



    更新Map
    1. 可变的Map  
    2. score("Bob") = 10 //更新  
    3. scores("Fred") = //增加  
    4. scores += ("Bob" -> 10, "Fred"-> 7)  
    5. scoers -= "Alice"  
    6.   
    7. 不可变Map, 假定当前scores是不可变  
    8. val new Scores = scores + ("Bob" -> 10, "Fred"-> 7) // 产生一个新的Map  
    9. 或者 当 scores 是 var变量  
    10. var scores = ...  
    11. scores = scores + ("Bob" -> 10, "Fred"-> 7)  
    12. scores = scores - "Alice"  

    迭代Map
    1. for( (k, v) <- Map) 处理 k 和 v  
    2. scores.keySet  <span style="white-space:pre">             </span>//一个类似 Set("Bob", "Cindy", "Alice")这样的集合  
    3. for(v <- scores.values) prinltn(v) <span style="white-space:pre">  </span>// 打印 10 8 7 10  
    4. for( (k, v) <- map) yield ( v, k )<span style="white-space:pre">   </span>//反转Map  

    排序Map
    1. 默认Scala给的是 哈希表,  
    2. val scores = scala.collections.immutable.SortedMap("Alice" -> 10, "Fred" -> 7, "Bob" -> 3, "Cindy" -> 8) // 如果需要<strong>排序</strong>,需要用树形Map  
    3.   
    4. 在Scala(2.9)中,还没有可变的 树形Map,只能用java的TreeMap  
    5.   
    6. 如果想按<strong>插入顺序</strong>访问所有键,可以用LinkedHashMap  
    7. val months = scala.collection.mutable.LinkedHashMap("Jan" ->1, ,"Feb" ->2, "Mar" ->3 , ...)  

    与Java的互操作
    1. Java -> Scala  
    2. 引入语句  
    3. import scala.collection.JavaConversions.mapAsScalaMap  
    4. val scores: scala.collection.mutable.Map[String, Int] = new java.util.TreeMap[String,Int]  
    5.   
    6. import scala.collection.JavaConversions.propertiesAsScalaMap  
    7. val props:scala.collection.Map[String,String] = System.getProperties()  
    8.   
    9. Scala -> Java  
    10. import scala.collection.JavaConversions.mapAsJavaMap  
    11. import java.awt.font.TextAttribute._  
    12. val attrs = Map(FAMILY -> "Serif" , SIZE -> 12)  
    13. val font = new javal.awt.Font(attrs) <span style="white-space:pre">       </span>//该方法预期一个Java Map  

    元组
    1. Map是k/v对偶的集合,对偶是元组最简单的形态, 元组是不同类型的值得聚集。  
    2. val t = (1,3.14,"Fred") <span style="white-space:pre">        </span>// Tuple3[Int, Double, java.lang.String]  
    3. val second = t._2 <span style="white-space:pre">          </span>// 元组位置从1开始,这里是 3.14  
    4. <span style="white-space:pre">                    </span>//t._2 可以携程 t _2, 中间变空格  
    5. val (first, second, thrid) = t <span style="white-space:pre">     </span>// first设为1, second 设为3.14, third设为 "Fred"  
    6. 当不需要所有部件时,,可以在不需要的位置上使用:  
    7. val (first, second, _) = t  
    8.   
    9. 元组用于函数需要范围不止一个值得情况,如StringOps的partition方法,返回包含满足和不满足某条件的字符:  
    10. "New York".partition(_.isUpper) <span style="white-space:pre">    </span>// ("NY" , "ew ork")  
    11.   
    12. 拉链操作  
    13. val symbols = Array("<", "-", ">")  
    14. val counts = Array(2, 10 , 2)  
    15. val pairs = symbols.zip(count) <span style="white-space:pre">     </span>// 输出对偶的数组, Array(("<", 2), ("-", 10), (">", 2))  
    16. for((s,n) <- pairs) Console.print(s * n)// <<---------->>  
    17. 用toMap方法可以将对偶的集合转换成Map  
    18. keys.zip(values).toMap<span style="white-space:pre">          </span>//keys是k集合, values是与之平行对应的v集合 
  • 相关阅读:
    java作用域public ,private ,protected 及不写时的区别
    Android开发环境部署
    java的WebService实践(cxf)
    Servlet小试
    XML内容作为String字符串读取报错
    myeclipse安装svn插件的多种方式
    一个简单的SpringMVC3 程序
    VS2010调试生成的文件
    双系统启动项修复
    安装服务命令
  • 原文地址:https://www.cnblogs.com/wzyxidian/p/4907498.html
Copyright © 2011-2022 走看看