1.Scala简介和安装
2.Scala语法介绍
3.Scala的函数
4.Scala中的集合类型
Scala提供了一套很好的集合实现,提供了一些集合类型的抽象。Scala集合分为不可变(immutable)的集合和可变(mutable)的集合。
scala的集合类型(collection)涵盖了如下类型:
数组(Array)、链表(List)、Set、Map、Tuple。
对于数组的使用,若想调用数组提供的方法,我们需要使用 import Array._引入包。
1.数组Array分为定长和变长两种数组。后期常用的类型是定长(Array)。
2.Scala的泛型的声明使用[]来定义的,不同于Java的<>。
3.Scala通过下标操作Array,使用()来操作,不同于Java的index。
定长数组:scala.collection.immutable.Array,一旦声明之后长度不可变。
变长数组:scala.collection.mutable.ArrayBuffer,动态数组。
范例:
//创建一个定长数组,一旦声明,长度不可变
val a1=Array(1,2,3,4)
//创建一个变长数组
val a2=ArrayBuffer(1,2,3)
//创建数组,并指定范围
val a3=Array[Int](1,2,3)
//通过下标操作数组
a1(1)
//> res0: Int = 2
//创建一个长度为3的定长数组
//注意,需要指定泛型类型。
val a4=new Array[Int](3)
赋值方式一:用for循环为数组var1赋值。
赋值方式二:为变长数组赋值,注意:变长数组提供了append方法用于赋值,并且隐式的改变数组长度。
示例:
//赋值
for(i<-0 to a4.length-1)a4(i)=i
a4
//> res1: Array[Int] = Array(0, 1, 2)
val v5=new ArrayBuffer[Int](3)
//变长数组可以通过append赋值
for(i<-0 to 10)v5.append(i)
取值方式一:根据数组下标取值。
取值方式二:利用for循环取值。
取值方式三:用高阶函数 foreach。
示例:
//通过下标操作数组
a1(1);a1(2);a1(0)
//利用for循环获取值
for (i <- a1) println(i)
a1.foreach{x=>println(x)}
用于将多个数组的结果合并在一起,import Array._。
合并时,数组的类型要一致,要么全是定长的,要么全是变长的,定长和变长之间不能进行合并。
示例:
val v6 = Array(1, 2, 3)
val v7 = Array(4, 5, 6)
//合并多个定长数组
val v8 = Array.concat(v6, v7)
//合并多个变长数组
val v9 = ArrayBuffer.concat(v5, a2)
创建区间数组,含头不含尾。
示例:
//创建区间数组
val v10 = Array.range(0, 5)
//创建区间数组,并指定步长为2
val v11 = Array.range(0, 5, 2)
val v12 = ArrayBuffer.range(0, 5)
返回一个包含一个函数的重复应用到初始值的数组。
示例:
//iterate将匿名函数应用到初始值,并返回指定长度的数组
val v13 = Array.iterate(1, 5)(x => x + 1)
val v131 = Array.iterate(1, 5)(_ * 2)
返回指定长度数组,每个数组元素为指定函数的返回值,默认从0开始。
示例:
//tabulate是将匿名函数应用到数组下标的函数,并返回指定长度的数组。
val v14 = Array.tabulate(5)(_ + 1)
val v141 = Array.tabulate(5)(_ * 2)
求和,对数组中的元素进行求和。
示例:
val v6 = Array(1, 2, 3)
//求和
v6.sum
最小值。
示例:
val v6 = Array(1, 2, 3)
//最小值
v6.min
最大值。
示例:
val v6 = Array(1, 2, 3)
//最大值
v6.max
排序,将数组元素排序。
调用格式:
scala.util.Sorting.quickSort(Array)
示例:
val v20=Array(1,4,3,2,6)
scala.util.Sorting.quickSort(v20)
v20
删除。
示例:
//去除头部n个元素,并返回去除后的数组
v6.drop(1)
//去除尾部n个元素,并返回去除后的数组
v6.dropRight(1)
取出头n个元素,并返回取出的元素数组。
示例:
//取出头n个元素,并返回取出的元素数组。
v6.take(1)
//取出末尾n个元素,并返回取出的元素数组。
v6.takeRight(1)
循环遍历。
示例:
v6.foreach { x => println(x) }
v6.foreach { println(_) }
改变集合类型中,元素的形式或数据,返回一个新的集合。此方法不会改变集合中元素的个数,只是改变了数值和形式。
示例:
val v15 = v6.map { x => x + 1 }
v6.map { _ * 1.0 }
v6.map { x => x.toDouble }
val v17 = Array("hello world", "hello hadoop")
v17.map { _.split(" ") }
底层用链表实现的数据结构。
定长列表:scala.collection.immutable.List,一旦声明之后长度不可变。
变长列表:scala.collection.mutable.ListBuffer,变长列表。
示例:
//声明一个定长List
val l1=List(1,2,3,4)
//声明一个变长List
val l2=ListBuffer(1,2,3)
val l3=List[Int](1,2,3)
val l4=1::2::3::Nil
//声明一个定长空List
val l5=List[Nothing]()
下标获取。
示例:
//通过下标取值
l9(0)
//> res9: Int = 4
返回头元素。
示例:
//返回头元素
l1.head
//> res0: Int = 1
去除头元素,并返回剩余元素的List,等价于drop(1)。
示例:
l1.tail
//> res1: List[Int] = List(2, 3, 4)
l1.drop(1)
//> res2: List[Int] = List(2, 3, 4)
判断是否为空。
示例:
l1.isEmpty
//> res3: Boolean = false
l5.isEmpty
//> res4: Boolean = true
①:::
拼接List,List类型需要一致。
示例:
l1:::l3
//> res5: List[Int] = List(1, 2, 3, 4, 1, 2, 3)
②concat
示例:
List.concat(l1,l3)
//> res6: List[Int] = List(1, 2, 3, 4, 1, 2, 3)
以指定数据填充,并返回新的List。
示例:
val l6=List.fill(5)("a")
//> l6 : List[String] = List(a, a, a, a, a)
创建n大小的数组,数组元素的下标按照传入的规则改变之后为当前下标的元素。
示例:
val l7=List.tabulate(5)(_*2)
//> l7 : List[Int] = List(0, 2, 4, 6, 8)
反转,并返回一个新的List
val l8=l1.reverse
//> l8 : List[Int] = List(4, 3, 2, 1)
①+:
从左侧添加元素,并返回新的List。
示例:
val l9=List(4,5,6)
//> l9 : List[Int] = List(4, 5, 6)
//从左侧添加元素,并返回新的List
3+:l9
//> res7: List[Int] = List(3, 4, 5, 6)
②:+
从右侧添加元素,并返回新的List。
示例:
l9:+7
//> res8: List[Int] = List(4, 5, 6, 7)
查看是否包含某个元素。
示例:
l9.contains(4)
//> res10: Boolean = true
拷贝元素到Array中。
示例:
var a1=new Array[Int](3)
//> a1 : Array[Int] = Array(0, 0, 0)
l9.copyToArray(a1, 0, l9.length)
a1
//> res11: Array[Int] = Array(4, 5, 6)
①toArray
转为数组类型。
示例:
l9.toArray
//> res12: Array[Int] = Array(4, 5, 6)
②toList
转变为链表。
示例:
a1.toList
//> res13: List[Int] = List(4, 5, 6)
去重,并返回一个新的List。
示例:
val l10=List(1,1,1,2,2,2,3,4,4,4)
l10.distinct
//> res14: List[Int] = List(1, 2, 3, 4)
通过匿名函数判断元素是否存在。
示例:
l10.exists { x => x%2==0 }
//> res15: Boolean = true
l10.exists { _%2==0 }
//> res16: Boolean = true
val l11=List(1,2,3,4,5,6)
//> l11 : List[Int] = List(1, 2, 3, 4, 5, 6)
l11.exists { x => x%2==0&&x>4 }
//> res17: Boolean = true
过滤。
示例:
l11.filter { x => x>3 }
//> res18: List[Int] = List(4, 5, 6)
l11.filter { _>3 }
//> res19: List[Int] = List(4, 5, 6)
l11.filter { x => x>3&&x%2==0 }
//> res20: List[Int] = List(4, 6)
查找指定元素第一次出现的位置,并返回位置。
示例:
l10.indexOf(1, 0)
//> res21: Int = 0
l10.indexOf(2, 3)
//> res22: Int = 3
val l12=List(1,2,3,1,2,3)
//> l12 : List[Int] = List(1, 2, 3, 1, 2, 3)
l12.indexOf(1, 1)
//> res23: Int = 3
获取交集,并返回值的List。
示例:
val l13=List(1,2,3)
val l14=List(3,4,5)
l13.intersect(l14)
//> res24: List[Int] = List(3)
//通过类型转换去使用API
val a2=Array(1,2,3)
val a3=Array(2,3,4)
a2.toList.intersect(a3.toList).toArray
//> res25: Array[Int] = Array(2, 3)
获取最后一个元素。
示例:
l13.head
//> res26: Int = 1
l13.last
//> res27: Int = 3
数组长度。
示例:
l13.length
//> res28: Int = 3
l13.map { x => x*2 }
//> res29: List[Int] = List(2, 4, 6)
l13.map { _*2 }
//> res30: List[Int] = List(2, 4, 6)
将集合中元素以指定分隔符返回,形成字符串。
示例:
l13.mkString
//> res31: String = 123
l13.mkString(",")
//> res32: String = 1,2,3
①sorted
升序排序,并返回一个List。
示例:
val l15=List(2,1,4,7,6)
l15.sorted
//> res33: List[Int] = List(1, 2, 4, 6, 7)
//降序
l15.sorted.reverse
//> res34: List[Int] = List(7, 6, 4, 2, 1)
②sortWith
//降序
l15.sortWith{(a,b)=>a>b}
//> res35: List[Int] = List(7, 6, 4, 2, 1)
l15.sortWith{_>_}
//> res36: List[Int] = List(7, 6, 4, 2, 1)
//升序
l15.sortWith{(a,b)=>a<b}
//> res37: List[Int] = List(1, 2, 4, 6, 7)
③sortBy
//重点掌握此排序
l15.sortBy{x=>x}
//> res38: List[Int] = List(1, 2, 4, 6, 7)
l15.sortBy{+_}
//> res39: List[Int] = List(1, 2, 4, 6, 7)
l15.sortBy{x=> -x}
//> res40: List[Int] = List(7, 6, 4, 2, 1)
l15.sortBy{-_}
//> res41: List[Int] = List(7, 6, 4, 2, 1)
l15.reduceLeft(_+_)
Scala Set(集合)是没有重复的对象集合,所有的元素都是唯一的。Scala 集合分为可变的和不可变的集合。
默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包。默认引用 scala.collection.immutable.Set。
//声明定长Set
val s1=Set(1,2,3)
//声明变长Set
val s2=scala.collection.mutable.Set(2,3,4)
val s3=Set(1,1,1,2,2,2)
//> s3 : scala.collection.immutable.Set[Int] = Set(1, 2)
//取交集
val s4=Set(1,2,3)
val s5=Set(3,4,5)
s4.&(s5)
//> res0: scala.collection.immutable.Set[Int] = Set(3)
s4&s5
//> res1: scala.collection.immutable.Set[Int] = Set(3)
①&~
//取差集
s4 &~ s5
//> res2: scala.collection.immutable.Set[Int] = Set(1, 2)
s5 &~ s4
//> res4: scala.collection.immutable.Set[Int] = Set(4, 5)
②diff
s4.diff(s5)
//> res3: scala.collection.immutable.Set[Int] = Set(1, 2)
s5.diff(s4)
//> res5: scala.collection.immutable.Set[Int] = Set(4, 5)
合并。
//合并
s4 ++ s5
//> res6: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)
返回满足匿名函数的元素个数。
s4.count { x => x>1 }
//> res7: Int = 2
s4.count(_>1)
//> res8: Int = 2
切割成两个set,其中一个set满足指定个数。返回的数据类型是Tuple(元祖)。
val s6=Set(1,2,3,4,5,6,7)
//> s6 : scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 7, 3, 4)
s6.splitAt(4)
Map(映射)是一种可迭代的键值对(key/value)结构。所有的值都可以通过键来获取。
Map 中的键都是唯一的。Map 也叫哈希表(Hash tables)。
Map有两种类型,可变与不可变,区别在于可变对象可以修改它,而不可变对象不可以。
默认情况下Scala使用不可变Map。如果你需要使用可变集合,你需要显式的引入 import scala.collection.mutable.Map 类
在Scala中你可以同时使用可变与不可变 Map,不可变的直接使用 Map,可变的使用 mutable.Map。
//声明定长map
val m1=Map("k1"->1,"k2"->2,"k3"->3)
//声明变长map
val m2=scala.collection.mutable.Map("k1"->1,"k2"->2,"k3"->3)
+=添加元素,只能用于变长map。
m2+=("k4"->4)
//> res0: Demo06.m2.type = Map(k2 -> 2, k4 -> 4, k1 -> 1, k3 -> 3)
获取所有key 。
val m3=Map("rose"->23,"tom"->25,"jim"->30)
//获取所有key
m3.keys
//> res1: Iterable[String] = Set(rose, tom, jim)
//获取所有的key并返回一个迭代器
m3.keys.foreach(x=>println(x))
获取所有的value。
m3.values
//> res2: Iterable[Int] = MapLike(23, 25, 30)
//获取所有的value,并返回一个迭代器
m3.values.foreach(println(_))
合并。
val m4=Map[String,Int]("k1"->1,"k2"->2)
val m5=Map[String,Int]("k3"->3,"k4"->4)
m4 ++ m5
//> res3: scala.collection.immutable.Map[String,Int] = Map(k1 -> 1, k2 -> 2, k3 -> 3, k4 -> 4)
是否包含指定key。
m4.contains("k1")
//> res4: Boolean = true
获取指定key的值,返回some类型
m4.get("k1")
//> res5: Option[Int] = Some(1)
//操作some类型,需要通过getOrElse来取值
//如果查找一个不存在的key,会返回指定的默认值,以避免报错
m4.get("k3").getOrElse(0)
//> res6: Int = 0
apply直接通过key取值,如果key不存在,则报错。
m4.apply("k1")
//> res7: Int = 1
清空map。只有变长map有此方法。
m2.clear()
过滤。
val m6=Map(1->"tom",2->"rose",3->"jim",4->"jary")
m6.filter(x=>x._1>2)
//> res8: scala.collection.immutable.Map[Int,String] = Map(3 -> jim, 4 -> jary)
m6.filter{case(k,v)=>k>2}
//> res9: scala.collection.immutable.Map[Int,String] = Map(3 -> jim, 4 -> jary)
返回元素个数
m6.size
与列表一样,元组也是不可变的,但与列表不同的是元组可以包含不同类型的元素。元组的值是通过将单个的值包含在圆括号中构成的。
用()来声明元组。元组是最灵活的一种数据结构。
//声明元组
val t1=(1,2,3,4,5)
val t2=(1,"hello",List(1,2,3),Array(2,3))
val t3=((1,2),("rose",23),(3,4))
val l1=List(1,2,(4,5))
元组的取值用._index (index的取值从1开始)
示例:
//元组取值,是从1开始的。
t1._1
//> res0: Int = 1
t1._3
//> res1: Int = 3
t3._2._1
//> res2: String = rose
应用:
val a1=Array("hello","world","hello","hadoop")
//要求,将a1里的元素改为:Array(("hello",1),("world",1)……)
val a2=a1.map { x => (x,1) }
//> a2 : Array[(String, Int)] = Array((hello,1), (world,1), (hello,1), (hadoop, 1))
//要求:操作a2还原回去
a2.map(x=>x._1)
上一篇:Scala的函数
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有