scala基础、数组相关操作、映射、元组

章节
  1. 基础
  2. 控制结构和函数
  3. 数组相关操作
  4. 映射和元组
1.基础[     ⬆TOP](#start)
  1. 在REPL中可以输入:paste来粘贴代码进去,ctrl+d结束。
    2.:quit推出REPL,:help显示帮助
  2. 在Scala中赋值动作是没有值的,或者是Unit类型,所以
x = y = 1    //赋值语句值是Unit类型,所以别把他们串接在一起,y=1值是()
  1. Scala没有++和–,使用+=和-=代替
    java中,a=a+1会被强制转换为更高的数据类型,a+=1不会被转换类型,也就是数据类型不变,两个计算结果一样的。还有+=的执行效率会稍微高一点,结果一样。区别的举例如下:
    a+=b –> a=(a.Type)(a+b);//返回的是a类型
    a=a+b –> a=a+b;//返回类型是a类型与b类型中的最高类型
2.控制结构和函数[     ⬆TOP](#start)
本章要点:
  • if表达式有值
  • 块也有值–是它最后一个表达式的值
  • Scala的for循环就像增强版的Java for循环
  • 分号不是必须的,void类型是Unit,避免在函数定义中使用return
  • 注意别再函数式定义中漏掉=。
  • 异常工作方式与Java和C++中基本一样,不同的是再catch语句中使用“模式匹配”
  • Scala没有受检异常
    1. Scala中没有switch语句,提供模式匹配机制,或者用if代替
    2. 循环
while (n > 0) {
    r = r * n
    n -=1
}
//Scala中没有for(;;)循环,有2个替代选择:使用while循环,或者使用如下:
for(i <- 1 to n)
    r = r * i  
  1. until返回一个不包含上限的区间
val s = "hello"
var sum = 0
for (i <- 0 until s.length)
    sum += s(i)
  1. Scala没有提供break和continue,如果需要,有如下几个方式:
a. 使用Boolean型的控制变量
b. 使用嵌套函数--你可以从函数中return
c. 使用Breaks对象中的break方法:
import scala.util.control.Breaks._
breakable{
    for(...){
        if(...) break; //退出breakable块,在这里,控制权是通过抛出和捕获异常完成的,因为时间很重要的话,应当避免使用这个套机制(效率低呗)
    }
}
  1. 高级for循环
scala> for (i <- 1 to 3;j <- 1 to 5) print((10*i+j)+" ")
11 12 13 14 15 21 22 23 24 25 31 32 33 34 35
//循环中定义变量
scala> for (i <- 1 to 3;from=4-i;j <- from to 3 if i!=j) print((10*i+j)+" ")
13 23 31 32

scala> for (i <- 1 to 4;from=4-i;j <- from to 3) print((10*i+j)+" ")
13 22 23 31 32 33 40 41 42 43
//for推导式
//如果for循环的循环体以yield开始,则循环会构造出一个集合,每次迭代成成集合中的一个值:
scala> for( i<- 1 to 10) yield i%3
res8: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)
注:变量<-表达式叫生成器,,每个生成器可以带一个“守卫”,以if开头Boolean表达式,,from这种叫做定义。也可以不用分号分割,用换行分割:
for { i <- 1 to 3   //生成式
    from = 4 -i     //定义
    j <- from to 3   //生成式  (这种相当于是2次循环,先i[0],匹配所有的j,再i[1]...)
}
  1. 函数
// 函数名  参数      函数体
def abs(x: Double) = if (x >= 0) x else -x

只要不是递归函数,不需要指定返回值类型,Scala编译器自动推断。
最后一个表达式是函数返回值,不建议使用return//递归函数
def fac(n: Int): Int = if (n < 0) 1 else n * fac(n - 1)

2.8 默认参数和带名参数

def decorate(str: String, leftString = "[", right: String = "]")  = left + str + right
调用参数可以不按照顺序:
decorate(left  = "<<<" ,str = "hello", right = ">>>")

2.9 变长参数

def sum(args: Int*) = {
    var result = 0
    for (arg <-args) result +=arg
    result
}
调用:
val s = sum(1,4,9,16,25)  //参数腰围Seq类型
错误调用:
scala> val s = sum(1 to 5)
<console>:12: error: type mismatch;
 found   : scala.collection.immutable.Range.Inclusive
 required: Int
       val s = sum(1 to 5)
修改:加上_* 告诉编译器希望这个参数当作参数序列处理
scala> val s = sum(1 to 5:_*)
s: Int = 15

2.10 过程
Scala对于不返回值的函数有特殊的表示法。如果函数体包含再花括号当中但没有前面的=号,那么返回类型就是Unit,这样的函数被称为过程(procedure)。过程不返回值,调用是为了它的副作用。如:

def box(s: String) {
    println(s+ "|")
}
//有人建议总是显式声明Unit返回值类型:
def box(s: String): Unit = {
    println(s+ "|")
}

2.11 懒值
当val被声明为lazy时,初始化将被推迟,直到首次对他取值。

scala> lazy val words = scala.io.Source.fromFile("c://errlog.txt").mkString
words: String = <lazy>
//在words被首次使用时取值(这里文件不存在也不会报错,使用时报错)
scala> lazy val words = scala.io.Source.fromFile("c://errlog.tx1t").mkString
words: String = <lazy>

scala> words
java.io.FileNotFoundException: c:\errlog.tx1t (系统找不到指定的文件。)
...
//在每一次words被使用时取值
scala> def words = scala.io.Source.fromFile("c://errlog.txt1").mkString
words: String

scala> words
java.io.FileNotFoundException: c:\errlog.txt1 (系统找不到指定的文件。)
...

2.12 异常
抛出的对象必须是java.lang.Throwable的子类。
Scala没有“受检”异常–不需要声明函数或者方法可能跑出某种异常

受检异常在编译期被检查,比如,需要再方法做出声明:
void Something() throws IOException.

thow表达式有特殊的类型Nothing,再if/else表达式中很有用。

if (x >= 0) {
    sqrt(x)    
} else
    throw new IllegalArgumentException("x should not be negative")
//第一个分支类型是Double,第二个分支类型是Nothing,因此if/else表达式类型是Double。

捕获异常采用模式匹配语法:

try{
    process(new URL("http://*****"))
} catch {
    case _: MalformedURLException => println("Bad URL:" + url)
    case ex :IOException => ex.printStackTrace()
}
3.数组相关操作[     ⬆TOP](#start)

3.1 定长数组

scala> val nums  = new Array[Int](10)//在JVM中Scala中Array以Java数组方式实现,这个对应JVM中就是个int[]
nums: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

scala> val a = new Array[String](10)
a: Array[String] = Array(null, null, null, null, null, null, null, null, null, null)

scala> val s = new Array("hello","world")   //已提供初始值的不需要new
<console>:11: error: too many arguments for constructor Array: (_length: Int)Array[T]
       val s = new Array("hello","world")
               ^
scala> val s = Array("hello","world")
s: Array[String] = Array(hello, world)

scala> s(0)  //使用()来访问,而不是[]
res15: String = hello

scala> s(0) = "goodbye"

scala> s
res17: Array[String] = Array(goodbye, world)

scala>

3.2 变长数组:数组缓冲
相当于java中ArrayList

scala> import scala.collection.mutable.Array
ArrayBuffer   ArrayBuilder   ArrayLike   ArrayOps   ArraySeq   ArrayStack

scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer

scala> val b = ArrayBuffer[Int]()  //或者val b = new ArrayBuffer[Int]
b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

scala> b += 1
res18: b.type = ArrayBuffer(1)

scala> b += (1,2,3,5)  //++=追加任何集合
res19: b.type = ArrayBuffer(1, 1, 2, 3, 5)

scala> b ++= Array(8,13,21)
res20: b.type = ArrayBuffer(1, 1, 2, 3, 5, 8, 13, 21)

scala> b.trim
trimEnd   trimStart

scala> b.trimEnd(5) //移除最后5个元素

scala> b
res23: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 1, 2)

b.insert(2,6)  //再下标2位置插入
b.insert(2,1,2,2,0)  //在下标2之前插入多个元素
b.remove(2)//移除下标为2元素
b.remove(2,3)//移除下标为2开始3个元素
b.toArray  //a.toBuffer  缓冲数组和数组的转换

3.3 遍历数组和数组缓冲

for (i <- 0 until a.length ){
     println(a(i))

}
for (i <- (0 until a.length).reverse ){
    println(i)

}

//如果是直接遍历元素,可以不需要下标:
 for(i <- a ) print(i)

3.4 数组转换

scala> val a  = Array[Int](2,3,4,5)    
a: Array[Int] = Array(2, 3, 4, 5)

scala> val result = for(elem <- a ) yield 2 * elem
result: Array[Int] = Array(4, 6, 8, 10)   //如果aArrayBuffer这里也是ArrayBuffer。这里result是一个新的数组,对a没有影响

3.4 常用算法

scala> val a = Array(2,9,4,3)
a: Array[Int] = Array(2, 9, 4, 3)

scala> a.max
res34: Int = 9

scala> a.sum
res35: Int = 18

scala> a.min
res36: Int = 2

scala> a.sorted   //排序
res37: Array[Int] = Array(2, 3, 4, 9)

scala> a.sortWith(_>_)
res38: Array[Int] = Array(9, 4, 3, 2)

scala> scala.util.Sorting.quickSort(a)   //直接修改了a,a不能是缓冲数组

scala> a
res40: Array[Int] = Array(2, 3, 4, 9)

scala> a.mkString
res41: String = 2349

scala> a.mkString(" and ")
res42: String = 2 and 3 and 4 and 9

scala> a.mkString("<",",",">")
res43: String = <2,3,4,9>
4.映射和元组[     ⬆TOP](#start)

4.1 操作

scala> val a = Array("a","b","c")
a: Array[String] = Array(a, b, c)

scala> val b = Array(1,2,3)
b: Array[Int] = Array(1, 2, 3)

scala> val pairs = a zip b   //拉链操作,个数要一致
pairs: Array[(String, Int)] = Array((a,1), (b,2), (c,3))

scala> for((k,v) <- pairs) print(k,v)
(a,1)(b,2)(c,3)
scala> val map = pairs.toMap   //集合转map
map: scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2, c -> 3)

scala> map.getOrElse("fff",100)
res58: Int = 100

//可变Map:scala.collection.mmutable.Map
//不可变Map:scala.collection.immutable.Map(默认是不可变Map)
//创建一个空的映射:
scala> val scores = new scala.collection.mutable.HashMap[String,Int]
scores: scala.collection.mutable.HashMap[String,Int] = Map()

scala> scores("Bob") = 10 //修改内容,这里报错,因为是不可表映射
//可通过这种方法修改,直接等于自己会报错如val scores = scores报错
val scores2 = scores + ("Bob" ->10 ,"Fred" -> 7)

4.6 与java的互操作

//只需要引入对应转换语句:
scala> import scala.collection.JavaConversions.
!=                  asScalaBuffer                getClass                  ne
##                  asScalaIterator              hashCode                  notify
+                   asScalaSet                   isInstanceOf              notifyAll
->                  bufferAsJavaList             iterableAsScalaIterable   propertiesAsScalaMap
==                  collectionAsScalaIterable    mapAsJavaConcurrentMap    seqAsJavaList
asInstanceOf        dictionaryAsScalaMap         mapAsJavaMap              setAsJavaSet
asJavaCollection    ensuring                     mapAsScalaConcurrentMap   synchronized
asJavaDictionary    enumerationAsScalaIterator   mapAsScalaMap             toString
asJavaEnumeration   eq                           mutableMapAsJavaMap       wait
asJavaIterable      equals                       mutableSeqAsJavaList      →
asJavaIterator      formatted                    mutableSetAsJavaSet


//java中TreeMap转Scala中Map
scala> import scala.collection.JavaConversions.mapAsScalaMap
 val scores : scala.collection.mutable.Map[String,Int] = new java.util.TreeMap[String,Int]


//java中java.util.properties转Map
import scala.collection.JavaConversions.propertiesAsScalaMap
val props : scala.collection.Map[String,String] = System.getProperties()

4.7 元组

scala> val t = (1,3.14,"Fred")
t: (Int, Double, String) = (1,3.14,Fred)

scala> val second = t._2   //元组下标从1开始,而不是0
second: Double = 3.14

scala> t _2   //也可以用这种方式来访问,中间空格
warning: there was one feature warning; re-run with -feature for details
res67: Double = 3.14

scala> val (first,second,third) = t  //直接映射结果
first: Int = 1
second: Double = 3.14
third: String = Fred

scala> val (first, second, _) = t //可能你只需要映射2个值
first: Int = 1
second: Double = 3.14
[     ⬆TOP](#start)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值