scala(2)

过程

在Scala中,定义函数时,如果函数体直接包裹在了花括号里面,而没有使用=连接,则函数的返回值类型就是Unit。这样的函数就被称之为过程。过程通常用于不需要返回值的函数。

scala> def sayHello(name:String) = "Hello," + name
sayHello: (name: String)String
scala> sayHello("ynn")
res24: String = Hello,ynn

scala> def sayHello(name:String){print("Hello,"+name);"Hello,"+name}  //过程
sayHello: (name: String)Unit
scala> sayHello("ynn")
Hello,ynn

scala> def sayHello(name:String):Unit="Hello,"+name
sayHello: (name: String)Unit
scala> sayHello("ynn")

lazy值

在Scala中,提供了lazy值的特性,也就是说,如果将一个变量声明为lazy,则只有在第一次使用该变量时,变量对应的表达式才会发生计算。这种特性对于特别耗时的计算操作特别有用,比如打开文件进行IO,进行网络IO等。

scala> import scala.io.Source._
import scala.io.Source._

scala> lazy val lines = fromFile("C://Users//96467//Desktop//scala//test.txt").mkString
lines: String = <lazy>
//即使文件不存在,也不会报错,只有第一个使用变量时会报错,证明了表达式计算的lazy特性
scala> val lines = fromFile("C://Users//96467//Desktop//scala//test.txt").mkString
java.io.FileNotFoundException: C:\Users\96467\Desktop\scala\test.txt (系统找不到指定的文件。)
  at java.io.FileInputStream.open0(Native Method)
  at java.io.FileInputStream.open(FileInputStream.java:195)
  at java.io.FileInputStream.<init>(FileInputStream.java:138)
  at scala.io.Source$.fromFile(Source.scala:91)
  at scala.io.Source$.fromFile(Source.scala:76)
  at scala.io.Source$.fromFile(Source.scala:54)
  ... 32 elided
  
scala> def lines = fromFile("C://Users//96467//Desktop//scala//test.txt").mkString
lines: String

异常

scala> :paste
// Entering paste mode (ctrl-D to finish)

try {
  throw new IllegalArgumentException("x should not be negative")
} catch {
  case _: IllegalArgumentException => println("Illegal Argument!")
} finally {
  print("release resources!")
}

// Exiting paste mode, now interpreting.

Illegal Argument!
release resources!
scala> import java.io._
import java.io._
scala> :paste
// Entering paste mode (ctrl-D to finish)

try {
 throw new IOException("io exception")
} catch {

  case _: IllegalArgumentException => println("Illegal Argument!")
}

// Exiting paste mode, now interpreting.

java.io.IOException: io exception
  at .liftedTree1$1(<console>:19)
  ... 37 elided
scala> :paste
// Entering paste mode (ctrl-D to finish)

try {
  throw new IOException("user defined exception")
} catch {
  case e1: IllegalArgumentException=> println("illegal argument")
  case e2: IOException=> println("io exception")
}

// Exiting paste mode, now interpreting.

io exception

数组

  1. Array
    在Scala中,Array代表的含义与Java中类似,也是长度不可改变的数组。此外,由于Scala与Java都是运行在JVM中,双方可以互相调用,因此Scala数组的底层实际上是Java数组。例如字符串数组在底层就是Java的String[],整数数组在底层就是Java的Int[]。
// 数组初始化后,长度就固定下来了,而且元素全部根据其类型初始化
scala> val s = new Array[Int](10)
s: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
scala> s(0)=1
scala> for (i <- 0 until s.length) println(s(i))    //遍历数组
1
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> a(1) = "ynn"
scala> print(a)
[Ljava.lang.String;@1c5f29c   //内存地址
scala> for (i <- 0 until a.length) println(a(i))
null
ynn
null
null
null
null
null
null
null

// 可以直接使用Array()创建数组,元素类型自动推断
scala> val c = Array("hello","world")
c: Array[String] = Array(hello, world)

scala> c(0)="hi"

scala> val d = Array("leo",4)
d: Array[Any] = Array(leo, 4)
  1. ArrayBuffer
    在Scala中,如果需要类似于Java中的ArrayList这种长度可变的集合类,则可以使用ArrayBuffer。
// 如果不想每次都使用全限定名,则可以预先导入ArrayBuffer类
scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer
// 使用ArrayBuffer()的方式可以创建一个空的ArrayBuffer
scala> val b = ArrayBuffer[Int]()
b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
// 使用+=操作符,可以添加一个元素,或者多个元素
scala> b += 1
res41: b.type = ArrayBuffer(1)

scala> b += (2, 3, 4, 5)
res42: b.type = ArrayBuffer(1, 2, 3, 4, 5)
// 使用++=操作符,可以添加其他集合中的所有元素
scala> b ++= Array(6, 7, 8, 9, 10)
res43: b.type = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// 使用trimEnd()函数,可以从尾部截断指定个数的元素
scala> b.trimEnd(5)

scala> for (e <- b)     //增强for遍历
     |   println(e)
1
2
3
4
5
// 使用insert()函数可以在指定位置插入元素
// 但是这种操作效率很低,因为需要移动指定位置后的所有元素
scala> b.insert(2,9)  
scala> for (e <- b) println(e)
1
2
9
3
4
5
6
scala> b.insert(3,5,6,7,8)
scala> for (e <- b) println(e)
1
2
9
5
6
7
8
3
4
5
6
// 使用remove()函数可以移除指定位置的元素
scala> b.remove(2,5)   //删除索引为2的后的5个数
scala> for (e <- b) println(e)
1
2
3
4
5
6
// Array与ArrayBuffer可以互相进行转换
scala> b.toArray
res13: Array[Int] = Array(1, 2, 3, 4, 5, 6)

scala> res13.toBuffer
res14: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6)

遍历数组

// 使用for循环和until遍历Array / ArrayBuffer
// 使until是RichInt提供的函数
scala> for (i <- 0 until b.length)
     |   println(b(i))
1
2
3
4
5
6
// 跳跃遍历Array / ArrayBuffer
scala> for (i <- 0 until (b.length,2))
     | println(b(i))
1
3
5
// 从尾部遍历Array / ArrayBuffer
scala> for (i <- (0 until b.length).reverse)
     | println(b(i))
6
5
4
3
2
1
// 使用“增强for循环”遍历Array / ArrayBuffer
scala> for (e <- b)
     |   println(e)
1
2
3
4
5
6

常见操作:

//创建Array数组
scala> val a = Array(1,2,34,5)
a: Array[Int] = Array(1, 2, 34, 5)
// 数组元素求和
scala> val sum = a.sum
sum: Int = 42
// 获取数组最大值
scala> val max = a.max
max: Int = 34
// 对数组进行排序
scala> scala.util.Sorting.quickSort(a)
// 获取数组中所有元素内容
scala> a.mkString
res20: String = 12534

scala> a.mkString(",")
res21: String = 1,2,5,34

scala> a.mkString("<",",",">")
res22: String = <1,2,5,34>
// toString函数
scala> a.toString        //Array数组返回内存地址
res23: String = [I@1617c6c

scala> b.toString        //ArrayBuffer数组返回数组内容
res24: String = ArrayBuffer(1, 2, 3, 4, 5, 6)

使用yield和函数式编程转换数组

scala> val a = Array(1,2,3,4,5)
a: Array[Int] = Array(1, 2, 3, 4, 5)
// 对Array进行转换,获取的还是Array
scala> val a2 = for (h <- a) yield h * h
a2: Array[Int] = Array(1, 4, 9, 16, 25)

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

scala> val b = ArrayBuffer[Int]()
b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

scala> b += (1,2,3,4,5)
res25: b.type = ArrayBuffer(1, 2, 3, 4, 5)
// 对ArrayBuffer进行转换,获取的还是ArrayBuffer
scala> val b2 = for (h <- b) yield h * h
b2: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 4, 9, 16, 25)
// 结合if守卫,仅转换需要的元素
scala> val a3 = for (h <- a if h % 2 == 0) yield h * h
a3: Array[Int] = Array(4, 16)

// 使用函数式编程转换数组(通常使用第一种方式)
scala> a.filter(_%2 == 0).map(2 * _)
res26: Array[Int] = Array(4, 8)
//filter 过滤数组中满足()中的条件
scala> a.filter{_%2 == 0}.map{2 * _}
res27: Array[Int] = Array(4, 8)

算法案例:移除第一个负数之后的所有负数

scala> :paste
// Entering paste mode (ctrl-D to finish)

var fnn = false
var arrayLength = a.length
var index = 0
while (index < arrayLength){
if(a(index)>=0){
index += 1
}else{
if(!fnn){fnn = true;index += 1}
else{a.remove(index);arrayLength -= 1}
}
}

// Exiting paste mode, now interpreting.

fnn: Boolean = true
arrayLength: Int = 6
index: Int = 6

scala> a.mkString(",")
res32: String = 1,2,3,4,5,-1

算法案例:移除第一个负数之后的所有负数(改良版)

// 重新构建数组
val a = ArrayBuffer[Int]()
a += (1, 2, 3, 4, 5, -1, -3, -5, -9)
keepIndexes (0,1,2,3,4,5)
a(keepIndexes(i))=Array(1,2,3,4,5,-1)
// 每记录所有不需要移除的元素的索引,稍后一次性移除所有需要移除的元素
// 性能较高,数组内的元素迁移只要执行一次即可
var foundFirstNegative = false
val keepIndexes = for (i <- 0 until a.length if !foundFirstNegative || a(i) >= 0) yield {
  if (a(i) < 0) foundFirstNegative = true
  i
}
//for (i <- 0 until keepIndexes.length) { a(i) = a(keepIndexes(i)) }
a.trimEnd(a.length - keepIndexes.length)

算法案例:移除第一个负数之后的所有负数(数据很多)

// 重新构建数组
val a = ArrayBuffer[Int]()
a += (1, 2, 3, 4, 5, -1, -3, -5, -9,6,7,-7,-3,10)
结果:Array(1,2,3,4,5,-1,6,7,10)
val b = ArrayBuffer[Int]()
// 每记录所有不需要移除的元素的索引,稍后一次性移除所有需要移除的元素
// 性能较高,数组内的元素迁移只要执行一次即可
var foundFirstNegative = false
val keepIndexes = for (i <- 0 until a.length if !foundFirstNegative || a(i) >= 0) yield {
  if (a(i) < 0) foundFirstNegative = true
  i
}
for (i <- keepIndexes) { b+=a(i) }

Map

  1. 创建不可变Map:
scala> val ages  =Map("yangning"->20,"wurong"->19,"bailu"->18)
scala> ages("yangning") = 12
会出错:<console>:13: error: value update is not a member of scala.collection.immutable.Map[String,Int]
       ages("yangning") = 12
       //如此创建的Map是不可变的
  1. 定义可变的Map:
scala> val ages = scala.collection.mutable.Map("yangning"->20,"wurong"->14)
ages: scala.collection.mutable.Map[String,Int] = Map(wurong -> 14, yangning -> 20)
scala> ages("yangning")=12
  1. 另一种创建方式:
scala> val ages = Map(("yangning",12),("wurong",13))
ages: scala.collection.immutable.Map[String,Int] = Map(yangning -> 12, wurong -> 13)
  1. 创建一个空的HashMap:
scala> val ages = new scala.collection.mutable.HashMap[String,Int]
ages: scala.collection.mutable.HashMap[String,Int] = Map()
  1. 访问Map元素:
scala> val ages = new scala.collection.mutable.HashMap[String,Int]    //创建一个空的HashMap
ages: scala.collection.mutable.HashMap[String,Int] = Map()

scala> ages("leo") = 23    //更新添加元素

scala> val Age = ages("leo")   //获取指定key对应的value,如果key不存在,会报错
Age: Int = 23

scala> val Age = if(ages.contains("leo")) ages("leo") else 0   //使用contains函数检查key是否存在
Age: Int = 23

scala> val Age = ages.getOrElse("leo",0)     //getOrElse函数
Age: Int = 23

scala> ages += ("Mike"->23,"Tom"->45)        // 增加多个元素
res8: ages.type = Map(Mike -> 23, leo -> 23, Tom -> 45)

scala> ages -= "leo"                      //移除元素
res9: ages.type = Map(Mike -> 23, Tom -> 45)
scala> val ages2 = ages + ("Mike"->34,"Tom"->40)
ages2: scala.collection.mutable.Map[String,Int] = Map(Mike -> 34, Tom -> 40)

scala> val ages3 = ages - "Tom"
ages3: scala.collection.mutable.HashMap[String,Int] = Map(Mike -> 23)
  1. 遍历Map:
scala> for ((key,value) <- ages) println(key + "" + value)  // 遍历map的entrySet
Mike23
Tom45

scala> for (key <- ages.keySet) println(key)  // 遍历map的key
Mike
Tom

scala> for (value <- ages.values) println(value)   // 遍历map的value
23
45

scala> for ((key,value) <- ages) yield (value,key)   // 生成新map,反转key和value
res15: scala.collection.mutable.HashMap[Int,String] = Map(23 -> Mike, 45 -> Tom)
  1. 排序
scala> val ages = scala.collection.immutable.SortedMap("leo"->23,"asd"->54,"fer"->32)   // SortedMap可以自动对Map的key的排序
ages: scala.collection.immutable.SortedMap[String,Int] = Map(asd -> 54, fer -> 32, leo -> 23)

scala> val ages = new scala.collection.mutable.LinkedHashMap[String,Int]    // LinkedHashMap可以记住插入entry的顺序
ages: scala.collection.mutable.LinkedHashMap[String,Int] = Map()

scala> ages("leo") = 23

scala> ages("tre") = 83

scala> ages("iuih") = 93

scala> for ((key,value) <- ages) println(key + ":" + value)
leo:23
tre:83
iuih:93

Tuple

  1. 简单Tuple:
scala> val t = ("leo",30)
t: (String, Int) = (leo,30)

scala> t._1     // 访问Tuple
res21: String = leo
scala> t._2
res22: Int = 30
  1. zip操作(拉链操作)
scala> val names = Array("leo","ynn","wii")
names: Array[String] = Array(leo, ynn, wii)

scala> val age = Array(23,12,54)
age: Array[Int] = Array(23, 12, 54)

scala> val nameage = names.zip(age)
nameage: Array[(String, Int)] = Array((leo,23), (ynn,12), (wii,54))

scala> for ((name,age) <- nameage) println(name + ":" + age)
leo:23
ynn:12
wii:54
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值