在Scala中,Array是定长数组类型,而ArrayBuffer类型是可变数组类型
import scala.collection.mutable.ArrayBuffer
object ArrayTest2{
def main(args: Array[String]): Unit = {
// 初始化一个长度为8的定长数组,器所有元素均为0
val arr1 = new Array[Int](8)
// 直接打印定长数组,内容为数组的hashcode值
println("arr1"+arr1)
// 将数组转换成数组缓冲,就可以看到源数组中的内容了
// toBuffer会将数组转换成长数组缓冲 初始化的int类型为 0
println("arr1.toBuffer"+arr1.toBuffer)
// toString 打印了 hashcode值
println("arr1.toString"+arr1.toString)
// 定义一个长度为3的定长数组
val arr2 = Array("Hadoop","Storm","Spark")
// 使用 () 来访问元素 数组的索引也是从 0 开始
print("arr3(2)="+arr2(2))
//////////////////////////////////////////////////////
println("-----------------------------------------------------------")
// 可变数组 (ArrayBuffer) 数组缓冲
// 使用可变数组需要导入 scala.collection.mutable.ArrayBuffer包
var ad = ArrayBuffer[Int]()
// 向数组缓冲的尾部追加一个元素 +=
ad += 1
// 追加多个元素,用元组类型包裹 +=
ad += (2,3,4,5)
println("ad1="+ad)
// 追加一个不变数组或可变数组 ++=
ad ++= Array(6,7)
ad ++= ArrayBuffer(8,9,10)
println("ad2="+ad)
// 在数组的某个位置插入元素 用insert(插入位置索引,插入数值1,插入数值2,....)
//ad.insert(0,-3,-2,-1)
println("ad3"+ad)
// 删除数组某个位置的元素用remove(删除位置的索引,从该位置的删除数量)
ad.remove(7,2)
println("ab4="+ad)
}
}
(1) 增强for循环
(2) until 关键字,生成Range类型: 0 until 100
scala> 0 until 10(包含0,但不包括10)
res1: scala.collection.immutable.Range = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
遍历数组相关代码如下:
object ArrayTraverse{
def main(args: Array[String]): Unit = {
// 初始化 一个数组
val arr = Array[Int](2,3,4,5,6,7,8,9,10)
// 1、增强for循环 <- 迭代法
for(i <- arr)
print(i+"\t")
println()
// 2、使用until关键字 ,利用下标索引
for(i <- (0 until arr.length))
print(arr(i)+"\t")
println()
// 3、 反转遍历 利用 range的 reverse 属性
println("反转变量")
for(i <- (0 until arr.length).reverse)
print(arr(i)+"\t")
}
}
yield 关键字将原始的数组进行转换会产生一个性的数组,原始的数组不变
数组类型的对象的map方法可以作用于数组的每个元素
scala> val arr = Array(1,2,3,4,5,6,7,8)
arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8)
scala> val res = for(e <-arr) yield e*2
res: Array[Int] = Array(2, 4, 6, 8, 10, 12, 14, 16)
scala> res
res5: Array[Int] = Array(2, 4, 6, 8, 10, 12, 14, 16)
scala> arr.map(_*2)
res6: Array[Int] = Array(2, 4, 6, 8, 10, 12, 14, 16)
遍历如下:
object ArrayTransfer{
def main(args: Array[String]): Unit = {
//定义一个数组
val arr = Array(1,2,3,4,5,6,7,8,9,10)
// 将arr的反序取数并分别乘10
println("arr: "+arr.toBuffer)
val arr2 = for(i <- (0 until arr.length).reverse) yield i*10
println("arr2: "+arr2)
// 将偶数取出,再乘以10
val arr3 = for (e <- arr if e % 2 ==0) yield e * 10
println("arr3: "+arr3.toBuffer)
// 更高级的写法
// 数组对象的filter属性是过滤,接收一个返回值为boolean的函数
// map相当于map中的方法作用于数组中每一个元素
val arr4 = arr.filter(_ % 2 == 0).map(_ * 10)
println("arr4: "+arr4.toBuffer)
}
}
数组对象有 sum\max\min\sorted等属性
scala> val arr= Array(2,5,1,4,3)
arr: Array[Int] = Array(2, 5, 1, 4, 3)
scala> arr.sum
res8: Int = 15
scala> arr.max
res9: Int = 5
scala> arr.min
res10: Int = 1
scala> arr.sorted
res12: Array[Int] = Array(1, 2, 3, 4, 5)
在Scala中,把哈希表这种数据结构称为映射Map,映射的组成:key,value,其中key是唯一的。
创建Map的方式一:->(箭头)
scala> val scores = Map("wangbaooqiang" -> 66,"huangbo" ->77,"yemin"->93)
scores: scala.collection.immutable.Map[String,Int] = Map(wangbaooqiang -> 66, huangbo -> 77, yemin -> 93)
scala> scores
res13: scala.collection.immutable.Map[String,Int] = Map(wangbaooqiang -> 66, huangbo -> 77, yemin -> 93)
创建Map的方式二:元组
scala> val scores2= Map(("yemin",66),("xuzheng",77),("huangbo",88))
scores2: scala.collection.immutable.Map[String,Int] = Map(yemin -> 66, xuzheng -> 77, huangbo -> 88)
scala> scores2
res14: scala.collection.immutable.Map[String,Int] = Map(yemin -> 66, xuzheng -> 77, huangbo -> 88)
–
scala> scores2
res14: scala.collection.immutable.Map[String,Int] = Map(yemin -> 66, xuzheng -> 77, huangbo -> 88)
获取map的value值 方法一 : ()
scala> scores2("yemin")
res16: Int = 66
获取map的value值 方法二 : get()
scala> scores2.get("yemin")
res17: Option[Int] = Some(66)
获取map的value值 方法二 : getOrElse()有就返回对应的值,没有就返回默认值
scala> scores2.getOrElse("yem",0)
res18: Int = 0
scala> scores2.getOrElse("yemmin",0)
res19: Int = 0
另外主要注意的是:
在Scala中有两种Map:
不可变的Map:在immutable包下的Map
可变的Map: 在mutable包下的Map
scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map
scala> val scores = Map("tom"->80,"greeye"-> 95)
scores: scala.collection.mutable.Map[String,Int] = Map(greeye -> 95, tom -> 80)
# 修改Map greeye对应的值为100
scala> scores("greeye") = 100
scala> scores
res21: scala.collection.mutable.Map[String,Int] = Map(greeye -> 100, tom -> 80)
# 追加键值对到Map中 +=
scala> scores +=("xiaoming"->101)
res25: scores.type = Map(greeye -> 100, tom -> 80, xiaoming -> 101)
总结:
1、是否可以修改值
Mutable包导入的map 可以修改map的值
Immutable包导入的map 不能修改里面的值
2、是否可以追加元素
mutable var/val 都可以追加元素(+=)
immutable var类型map可以追加,val类型数据不能追加元素
元组(tuple)是一个映射的特点:
1、元组是不可变的
2、元组的元素可以包含各种不同的类型元素,这个相对于array、map和set是很大的不同,
3、对偶元组可以转化成map映射类型
4、可以通过数组对象类型的zip方法将两个array类型绑定成对偶元组
定义元组是用小括号将多个元素包在起来,元素之间用逗号分隔,元素的类型可以不一样,元素个数可以任意多个
scala> val t = ("hadoop",3.14,65535)
t: (String, Double, Int) = (hadoop,3.14,65535)
有两种获取方式:
第一种方法是 等式分解,这种方式需要左边比元组内元素的个数多一个数,适合小数量元组
第二种方法是 下标获取_1,_2 可以通过固定的下标,获取对应位置的的元组元素
scala> val t = ("hadoop",3.14,65535)
t: (String, Double, Int) = (hadoop,3.14,65535)
# 第一种方式获取元组的元素值
scala> val tt,(a,b,c) = t
tt: (String, Double, Int) = (hadoop,3.14,65535)
a: String = hadoop
b: Double = 3.14
c: Int = 65535
scala> a
res28: String = hadoop
scala> b
res29: Double = 3.14
scala> c
res30: Int = 65535
# 第二种方式获取元组的元素值,下标获取 _1 _2 _3
scala> val t1 = t._1
t1: String = hadoop
scala> t1
res35: String = hadoop
# 将多个对偶元组整合成array数组
scala> var arr = Array(("tom",88),("jerry",95))
arr: Array[(String, Int)] = Array((tom,88), (jerry,95))
# toMap可以将对偶的集合转换成映射
scala> val m = arr.toMap
m: scala.collection.immutable.Map[String,Int] = Map(tom -> 88, jerry -> 95)
scala> var va = Array(77,66,99)
va: Array[Int] = Array(77, 66, 99)
scala> var ke = Array("ye","min","Greeye")
ke: Array[String] = Array(ye, min, Greeye)
# zip的是将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的array数组
scala> ke.zip(va)
res52: Array[(String, Int)] = Array((ye,77), (min,66), (Greeye,99))
scala> val keva = ke.zip(va)
keva: Array[(String, Int)] = Array((ye,77), (min,66), (Greeye,99))
scala> keva.toMap
res54: scala.collection.immutable.Map[String,Int] = Map(ye -> 77, min -> 66, Greeye -> 99)
注意: 如何两个数组的元素个数不一样,拉链的元组长度以较小的为准
Scala 集合类系统地区分了可变的和不可变的集合。可变集合可以在适当的地方被更新或扩展。这意味着你可以修改,添加,移除一个集合的元素。而不可变集合类,相比之下,永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变。
所有的集合类都可以在包scala.collection或scala.collection.mutable,scala.collection.immutable,scala.collection.generic中找到。
客户端代码需要的大部分集合类都独立地存在于3种变体中,它们位于scala.collection, scala.collection.immutable, scala.collection.mutable包。
- scala.collection.immutable:包是的集合类确保不被任何对象改变。例如一个集合创建之后将不会改变。因此,你可以相信一个事实,在不同的点访问同一个集合的值,你将总是得到相同的元素。
默认情况下,Scala 一直采用不可变集合类。例如,如果你仅写了Set 而没有任何加前缀也没有从其它地方导入Set,你会得到一个不可变的set,另外如果你写迭代,你也会得到一个不可变的迭代集合类,这是由于这些类在从scala中导入的时候都是默认绑定的。为了得到可变的默认版本,你需要显式的声明collection.mutable.Set或collection.mutable.Iterable.
一个有用的约定,如果你想要同时使用可变和不可变集合类,只导入collection.mutable包即可。
import scala.collection.mutable //导入包scala.collection.mutable
集合树的最后一个包是collection.generic。这个包包含了集合的构建块。集合类延迟了collection.generic类中的部分操作实现,另一方面集合框架的用户需要引用collection.generic中类在异常情况中。
为了方便和向后兼容性,一些导入类型在包scala中有别名,所以你能通过简单的名字使用它们而不需要import。这有一个例子是List 类型,它可以用以下两种方法使用,如下:
scala.collection.immutable.List // 这是它的定义位置
scala.List //通过scala 包中的别名
List // 因为scala._ // 总是是被自动导入。
在Scala中列表要么为空(Nil表示空列表)要么是一个head元素加上一个tail列表。
List的操作符有 :: +: ++
其中 :: +: 是针对元素插入列表 ++是列表 加 列表
另外 :: 符号是右结合的方式,
比如9 :: 5 :: 2 :: Nil相当于 9 :: (5 :: (2 :: Nil))
object SeqTest{
def main(args: Array[String]): Unit = {
// 创建一个不可变的集合
val lit1 = List(1,2,3)
// 将0插入到集合List1的前面生成一个新的list ::
val lit2 = 0 :: lit1
// 插入列表2 .::
val lit3 = lit1.::(4)
// 插入列表3 0+=
val lit4 = 0 +: lit1
// 插入列表4 .+:
val lit5 = lit1.+: (0)
println("lit1="+lit1)
println("lit2="+lit2)
println("lit3="+lit3)
println("lit4="+lit4)
println("lit4="+lit5)
// 将4 插入到集合list1的后面生成一个新的list
val lit6 = lit1 :+ 4
println("lit6= "+lit6)
//将2个List集合合并成一个新的list集合
val list0 = List(7,8,9)
println("list0="+list0)
// ++ 合并集合的符号
val lit7 = lit1 ++ list0
println("lit7="+lit7)
// 将list0 插入到lit1 的前面生成一个新的集合
val lit8 = list0 ++ lit1
print("lit8="+lit8)
}
}
import scala.collection.mutable.ListBuffer
object MutableSqlTest{
def main(args: Array[String]): Unit = {
// 构建一个可变序列
val lit1 = ListBuffer[Int](1,2,3)
// 创建一个空的可变序列
val lit2 = new ListBuffer[Int]
val lit3 = ListBuffer[Int](elems = 4,5,6)
// 向 list 中追加元素: 注意是在现有列表中追加,没有生成新的集合
lit1 ++= lit3 // ++=
println("lit1 3="+lit1)
// lit1和lit2合并成一个新的lit集合,注意:生成新的集合
val lit4 = lit1 ++ lit2
println("lit4="+lit4)
// 将元素追加到lit1后面生成一个新的集合
val lit5 = lit1 :+ 9
// 将元素追加到lit1前面生成一个新的集合
// 在可变列表的前面加元素?
//val lit6 = lit1.::(8)
println("lit5="+lit5)
}
}
import scala.collection.immutable.HashSet
object ImmutableSet{
def main(args: Array[String]): Unit = {
// 创建一个空的set
val set1 = new HashSet[Int]()
println("set1="+set1)
// 将元素和set合并生成一个新的set,原有set不变 +
val set2 = set1 + 4
println("set2="+set2)
// set集合元素不会重复
val set3 = set1 ++ Set(5,6,7)
println("set3="+set3)
// set 元素 之间相加 ++
val set4 = Set(4,5,6) ++ set3
println("set="+set4)
}
}
import scala.collection.mutable
object MutableSet{
def main(args: Array[String]): Unit = {
// 创建一个可变的set
val set1 = new mutable.HashSet[Int]()
println("list1="+set1)
// 向 set1 中添加元素
set1+=4
// add 等价于 +=
set1.add(5)
// 集合合并 ++=
set1 ++=Set(6,7,8)
println("Set1="+set1)
// 删除一个元素
set1 -= 8
set1.remove(7)
println("set1="+set1)
}
}
Scala 中使用关键字lazy来定义惰性变量,实现延迟加载(懒加载)
惰性变量只能是不可变变量,并且只有在调用惰性变量时,才会实例化这个变量
object ScalaLazyDemo {
def init():String = {
println("huangbo 666")
return "huangbo"
}
def main(args: Array[String]): Unit = {
lazy val name = init();
println("666")
println(name)
}
}
在声明name时,并没有立即调用实例化方法initName(),而是在使用name时,才会调用实例化方法,并且无论缩少次调用,实例化方法只会执行一次。