转载:

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
  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方法
  1. 不像java用 强制类型转换,而是用方法
  2. 99.44.toInt         //99, 这里不带参数,并且不改变当前对象的方法 通常不实用圆括号
  3. 99.toChart      //'c'
  4. 99.toString         //"99"
  5. "99.44".toDouble    // 99.44
  1. "Hello"(4) // '0'
  2. 实际上是StringOps类的apply方法
  3. def apply(n:Int) : Char
  4. "Hello".apply(4) // 完整写法
  5. BigInt伴生对象的apply方法:
  6. BigInt("1234567890") // BigInt.apply("1234567890")
  7. BigInt("123") * BigInt("123")
  8. 数组Array,也是伴生对象
  9. Array(1,4,9,16)
  1. if (x > 0) 1 else -1
  2. 可以将if/else表达式的值赋给变量
  3. val s = if(x > 0) 1 else -1
  4. 每个表达式都有一个类型
  5. if(x > 0) 1 else -1  // Int
  6. if(x > 0) "p" else -1 // Any (Int 和String的超类)
  7. if(x > 0) 1   // (),Unit类,因为可能没有输出值,即if(x >0) 1 else ()
  8. while(n > 0){
  9. r = r*n
  10. n -=1
  11. }
  1. for( i <- 表达式)
  2. for( i <- 1 to 10)
  3. r = r*i
  4. val s = "Hello"
  5. var sum = 0
  6. for( i <- 0 until s.length)
  7. sum+= s(i)
  8. 简化版:
  9. var sum = 0
  10. for(ch <- "Hello") sum+=ch
  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. for(i <- 1 to 3; j <- 1 to 3 if i != j)print((10 * i + j)+ "")
  4. 12 13 21 23 31 32
  5. 注意在if前没有分号
  6. for(i <- 3; from = 4 - i ; j <- from to 3) print((10 * i + j) + " ")
  7. 31 22 23 31 32 33
  8. for( i <- 1 to 10) yield i % 3
  9. 生成 Vector(1,2,0,1,2,0,1,2,0,1)
  10. 推导式生成的集合与第一个生成器是类型兼容的:
  11. for( c<- "Hello"; i<- 0 to 1) yield (c + i).toChar
  12. "Hilflmlmop"
  13. for(i <- 0 to 1; c <- "Hello") yield (c + i).toChar
  14. Vector('H','e','l',''l','o','I','f','m','m','p')
  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. 一般定义函数无需指定返回类型,Scala可以通过=符号右侧的表示式的类型推断返回类型,除非是递归函数。
  8. def fac(n:Int) :Int = if(n<=0) 1 else n* fac(n-1)// 如果没有返回类型,Scala无法校验 n*fac(n-1)的类型是Int
  1. def decorate(str:String, left:String="[", right:String ="]") = left + str +right
  2. decorate("Hello", "<<<", ">>>")           // <<<Hello>>>
  3. decorate("Hello","<<<")                // <<<Hello]
  4. decorate(left = "<<<", str = "Hello" , right = ">>>")     // 指定参数名,<<<Hello>>>
  5. decorate("Hello", right=">>>")             // 混用
  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. val s = sum(1 to 5)                     // 错误
  8. val s = sum(1 to 5: _*)                 //将 1 to 5当做参数序列处理
  9. 递归中使用
  10. def recursiveSum(args : Int *): Int = {
  11. if (args.length ==0) 0
  12. else args.head + recursiveSum(args.tail:_*)       // head是首个元素, tail是所有其他元素的序列,是一个Seq
  13. }
  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. 可以把懒值当做介于 val和def的中间状态:
  3. val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString//在words被定义时即被取值
  4. lazy val words= scala.io.Source.fromFile("/usr/share/dict/words").mkString//在首次调用
  5. 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. }catch{
  4. case _: MalformedURLException => println("Bad Url:" + url)
  5. case ex: IOException => ex.printStackTrace()
  6. }
  7. var in = new URL("http://xxx.com").openStream()
  8. try{
  9. process(in)
  10. }finally{
  11. in.close()
  12. }
  13. 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. import scala.collection.mutable.ArrayBuffer
  8. val b = ArrayBuffer[Int]()          // 伴生对象的apply
  9. //或者 new ArrayBuffer[Int]
  10. b += 1                          //(1)
  11. b += (1,2,3,5)                  // (1,1,2,3,5)
  12. b ++= Array(8,13,21)                // 可以用++=追加任何集合 (1,1,2,3,5,8,13,21)
  13. b.trimEnd(5)                    //移除最后5个元素 , (1,1,2)
  14. b.insert(2,6)                   // (1,1,6,2)
  15. b.insert(2,7,8,9)               // (1,1,7,8,9,6,2)
  16. b.remove(2)                     // (1,1,8,9,6,2)
  17. b.remove(2,3)                   //(1,1,2)
  18. b.toArray                   // Array(1,1,2) ,变长转定长
  19. a.toBuffer                  // 定长转变长

遍历数组

  1. for(i <- 0 until.a.length)
  2. println(i + ": " + a(i))
  3. 如果在循环体中不需要下表
  4. for(elem <- a )
  5. 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. for(elem <- a if elem %2 ==0) yield 2 * elem
  5. 另一种做法
  6. 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. val b = ArrayBuffer(1,7,2,9)
  4. val bSorted = b.sorted(_ < _) <span style="white-space:pre">               </span>// (1,2,7,9) 这里b没有改变,可以提供一个比较函数,用sortWith方法
  5. val a = Array(1,7,2,9)
  6. scala.util.Sorting.quickSort(a) <span style="white-space:pre">            </span>// 此方法不适于ArrayBuffer
  7. a.mkString(" and ") <span style="white-space:pre">                    </span>// "1 and 2 and 7 and 9"
  8. 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. var triangle = new Array[Array[Int]](10)
  6. for(i <- 0 until triangle.length)
  7. 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. 反过来,把Java.until.List,自动转换成一个Buffer
  8. import scala.collection.JavaConversions.asScalaBuffer
  9. import scala.collection.mutable.Buffer
  10. val cmd :Buffer[String] = pb.command()
  11. // java to scala, 不能使用ArrayBuffer, 包装起来的对象仅能保证是个Buffer

4、映射和元素

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

更新Map

  1. 可变的Map
  2. score("Bob") = 10 //更新
  3. scores("Fred") = 7 //增加
  4. scores += ("Bob" -> 10, "Fred"-> 7)
  5. scoers -= "Alice"
  6. 不可变Map, 假定当前scores是不可变
  7. val new Scores = scores + ("Bob" -> 10, "Fred"-> 7) // 产生一个新的Map
  8. 或者 当 scores 是 var变量
  9. var scores = ...
  10. scores = scores + ("Bob" -> 10, "Fred"-> 7)
  11. 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. 在Scala(2.9)中,还没有可变的 树形Map,只能用java的TreeMap
  4. 如果想按<strong>插入顺序</strong>访问所有键,可以用LinkedHashMap
  5. 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. import scala.collection.JavaConversions.propertiesAsScalaMap
  6. val props:scala.collection.Map[String,String] = System.getProperties()
  7. Scala -> Java
  8. import scala.collection.JavaConversions.mapAsJavaMap
  9. import java.awt.font.TextAttribute._
  10. val attrs = Map(FAMILY -> "Serif" , SIZE -> 12)
  11. 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. 元组用于函数需要范围不止一个值得情况,如StringOps的partition方法,返回包含满足和不满足某条件的字符:
  9. "New York".partition(_.isUpper) <span style="white-space:pre">    </span>// ("NY" , "ew ork")
  10. 拉链操作
  11. val symbols = Array("<", "-", ">")
  12. val counts = Array(2, 10 , 2)
  13. val pairs = symbols.zip(count) <span style="white-space:pre">     </span>// 输出对偶的数组, Array(("<", 2), ("-", 10), (">", 2))
  14. for((s,n) <- pairs) Console.print(s * n)// <<---------->>
  15. 用toMap方法可以将对偶的集合转换成Map
  16. keys.zip(values).toMap<span style="white-space:pre">          </span>//keys是k集合, values是与之平行对应的v集合

快学Scala第一部分的更多相关文章

  1. 快学Scala 第一课 (变量,类型,操作符)

    Scala 用val定义常量,用var定义变量. 常量重新赋值就会报错. 变量没有问题. 注意:我们不需要给出值或者变量的类型,scala初始化表达式会自己推断出来.当然我们也可以指定类型. 多个值和 ...

  2. 快学Scala习题解答—第一章 基础

    1 简介 近期对Scala比较感兴趣,买了本<快学Scala>,感觉不错.比<Programming Scala:Tackle Multi-Core Complexity on th ...

  3. 《快学Scala》

    Robert Peng's Blog - https://mr-dai.github.io/ <快学Scala>Intro与第1章 - https://mr-dai.github.io/S ...

  4. 快学Scala 第十九课 (trait的abstract override使用)

    trait的abstract override使用: 当我看到abstract override介绍的时候也是一脸懵逼,因为快学scala,只介绍了因为TimestampLogger中调用的super ...

  5. 《快学Scala》第一章 基础

  6. 快学Scala 2

    控制结构和函数 1.在Scala中,几乎所有构造出来的语法结构都有值.这个特性是为了使得程序更加精简,也更易读. (1)if表达式有值 (2)块也有值——是它最后一个表达式的值 (3)Scala的fo ...

  7. 《快学Scala》——数组、映射和元组

    数组 定长数组:在Scala中可以用Array,初始化一个定长数组.例如: val nums = new Array[Int](10) //10个整数的数组,所有元素初始化为0 val a = new ...

  8. 《快学Scala》——控制结构和函数

    条件表达式 在Scala中if/else表达式有值,这个值就是跟在if或else之后的表达式的值.例如: if (x > 0) 1 else -1 上述表达式的值是1或-1,具体是哪一个取决于x ...

  9. 快学scala

    scala 1.   scala的由来 scala是一门多范式的编程语言,一种类似java的编程语言[2] ,设计初衷是要集成面向对象编程和函数式编程的各种特性. java和c++的进化速度已经大不如 ...

随机推荐

  1. Qt 学习之路:QStringListModel

    上一章我们已经了解到有关 list.table 和 tree 三个最常用的视图类的便捷类的使用.前面也提到过,由于这些类仅仅是提供方便,功能.实现自然不如真正的 model/view 强大.从本章起, ...

  2. Vector/Arraylist与Linklist的区别

        SDK提供了有序集合接口java.util.List的几种实现,其中三种最为人们熟知的是Vector.ArrayList和    LinkedList.有关这些List类的性能差别是一个经常被 ...

  3. Java基础知识强化之集合框架笔记32:集合之可变参数的概述和使用

    1. 可变参数的概述和使用: (1)可变参数:定义方法的时候不知道该定义多少个参数(2)格式:     修饰符  返回值类型  方法名(数据类型… 变量名){   }  注意: 这里的变量其实是一个数 ...

  4. 第一篇:python基础

    python基础   python基础 本节内容 python起源 python的发展史 为什么选择python3 第一个python程序 变量定义 表达式和运算符 用户输入 流程控制 判断 流程控制 ...

  5. sql知识点的积累和使用过的例子

    越来越发现自己的sql方面的知识的欠缺,所以只能放低姿态一点一点的学了 一 游标和charIndex的使用. 游标我一直没用过,以前只是在同事们写的存储过程里见过,但是一直没看明白(可是我就是比较笨吧 ...

  6. JQ 让光标在文本框最末尾

    function setFocus() { //文本末尾获得焦点 var obj = event.srcElement; var txt = obj.createTextRange(); txt.mo ...

  7. Use StringBuilder instead of String as possible as you can.

    If you are care a littile about the time your algorithm cost,you should notice that,you my use Strin ...

  8. padding and margin.

    padding is the space between the content and the border, whereas margin is the space outside the bor ...

  9. 强制关闭myeclipse出现的问题

    重启时,可能会出现打不开关闭前所在的workspace.其他workspace可以正常打开. 今天遇到这个问题,以前就遇到过,但是忘记如何解决了.今天在我等了十多分钟后,神奇的myeclipse自己起 ...

  10. Swift中共有74个内建函数

    Swift中共有74个内建函数,但是在Swift官方文档(“The Swift Programming Language”)中只记录了7中.剩下的67个都没有记录.   本文将列举Swift所有的内建 ...