【Scala】基础4:集合——List、Set和Map

List

一个不可变的单链表,可以作为一个函数调用List来创建一个列表,并以逗号分隔参数的形式传入列表的内容。

同Java中一样,如果没给List指定泛型,列表中可以存放不同数据类型的元素。指定泛型后,只能存放某一特定数据类型的元素。

要直接访问单个元素,可以作为一个函数来调用这个列表,并传入该元素的索引(从0开始)

可以用head()方法访问一个列表的首元素,可以用tail()方法以List的形式返回剩余元素

举例:

val numbers=List("一","二","三",1,2,3)
    
val nums=List[Any]("一","二","三",1,2,3)
    
val colors=List[String]("red","yellow","blue")
    
println(s"I have ${colors.size} colors:${colors}")
    
println(colors(1))    //访问下标为1的元素
    
println(colors.head)
    
println(colors.tail)

遍历列表

①for循环迭代

val nums=List[Any]("一","二","三",1,2,3)
for(i <- nums){
    println(i)
}

②foreach()函数

foreach()函数的参数是一个函数,对列表中的每一项分别调用这个函数

val colors=List[String]("red","yellow","blue")

colors.foreach((c:String) => println(c))

//使用通配符
colors.foreach(println(_))

//在foreach里执行println时,也可以直接写下面的
colors.foreach(println)

判断List非空的方法:① list.size>0

                                   ② !list.isEmpty

                                   ③ list.nonEmpty

                                   ④ list!=Nil(其中Nil表示空列表)

map()函数

map()函数的参数为一个函数,可以将一个列表的每个元素转换为另一个值或类型,并以列表的形式返回

map函数特点:

①map之前是列表,map之后依然是列表

②map之前有几个元素,map之后依然有几个元素

③唯一改变的是元素的内容,具体如何变化要取决于参数函数。

val colors=List[String]("red","yellow","blue")

val size=colors.map((s:String) => s.size)

//使用通配符
val size=colors.map(_.size)

println(size)

flatMap()函数

先调用一次map函数,然后调用flatten函数扁平化,拆成一个List。

val colors = List("red","yellow","blue")
    
val res = colors.flatMap(_.split("e"))
    
println(res)

reduce()函数

reduce()函数的参数为一个函数,而且这个函数的参数必须为两个,可以将列表中的元素结合成一个元素,具体返回什么取决于参数函数的逻辑。

val datas=List(32,95,24,27,11)
    
val total=datas.reduce((x:Int,y:Int) => x+y)
    
//使用通配符
val total=datas.reduce((_+_)

println(total)

filter()过滤器

filter()函数的参数为一个函数,而且这个函数的返回类型必须是布尔,只有当返回值为true时才将元素加入到结果中。

val datas=List(32,95,24,27,11)
    
val odds=datas.filter((x:Int) => x%2==1)

//使用通配符
val odds=datas.filter(_%2==1)
    
println(odds)

操作符 ::

又叫cons操作符

使用Nil作为基础,并使用右结合的cons操作符(::)绑定元素,就可以构建一个列表,而不必使用传统的List(...)格式。

使用cons操作符时,最右侧的元素作为容器,可以使用一个列表或Nil,相当于向列表头添加元素

使用 :+ 可以进行反向操作,向列表尾添加元素。例如:val append = List(1,2,3,4) :+ 5

举例:

val numbers = 1::2::3::Nil

val numbers1= 4::numbers

val numbers2 = 1::2::3::Nil::List(1,2,3)

//结果 numbers:List[Int] = List(1,2,3)
//结果 numbers2:List(1, 2, 3, List(), 1, 2, 3)

那么,如果想将容器放在左侧,也就是说想实现左结合,应该怎么办呢?

可以在cons操作符前面加一个 . 实现左结合,左结合依然是向表头添加元素。

val num=Nil .:: (1) .:: (List(4,5,6)) .:: (3)

println(num)

 操作符 :::

从上面的例子中可以看出,List也会作为一个整体被放入列表中。

如果只是想将4,5,6这三个数放入列表中,如何实现呢?

使用 ::: 操作符,可以向一个列表中追加另一个列表中的元素。这也是一个右结合操作符,和cons操作符一样,在前面加一个 . 就变成了左结合操作符

val num1 =List(1,2,3) ::: List(4,5,6)
    
val num2=List(1,2,3) .::: (List(4,5,6))
    
println(num1)
    
println(num2)

操作符 ++

++的作用和 ::: 的作用完全相同,区别在于 ::: 后面只能使用List,而++后面既可以使用List,还可以使用Set和Map

val test = List(1,2,3) ++ Map("a" -> 0)

操作符 ==

判断两个集合(List、Set、Map)内容是否相等

常用方法:

方法名 描述 示例
drop 从列表中去除前n个元素
val list=List(1,2,3,4,5)
val resList = list.drop(2)
//或者val resList2 = list drop 2
dropRight 从列表中去除后n个元素
val list=List(1,2,3,4,5)
val resList = list.dropRight(2)
//或者val resList2 = list dropRight 2
take 从列表中抽取前n个元素
val list=List(1,2,3,4,5)
val resList = list.take(2)
//或者val resList2 = list take 2
takeRight 从列表中抽取后n个元素
val list=List(1,2,3,4,5)
val resList = list.takeRight(2)
//或者val resList2 = list takeRight  2
flatten 扁平化,将一个列表的列表转换为元素列表
val list = List(List(1,2,3,4,5),List(6,7,8,9,10))
val resList = list.flatten
partition partition函数的参数为一个函数,而且这个函数的返回值一定是布尔类型,可以将列表分组为两个列表构成的元组
val list = List(1,2,3,4,5)
val resList = list.partition(_<3)
slice 返回第一个和第二个索引中间部分(前闭后开)
val list = List(1,2,3,4,5)
val resList = list.slice(1,3)
splitAt 按数字个数拆分成两个列表,前n个为一个列表,剩下的为一个列表
val list = List(1,2,3,4,5)
val resList = list.splitAt(4)
sortBy 按给定函数返回的值对列表排序
val fruits = List("apple","pear","banana")
val res=fruits.sortBy(_.size)
sorted 按自然值对核心Scala类型列表排序
val fruits = List("apple","pear","banana")
val res=fruits.sorted
sortWith 给定规则对列表排序
val fruits = List("apple","pear","banana")
val res=fruits.sortWith(_>_)    //从大到小排序
distinct 返回不包含重复元素的列表版本
val numbers = List(3,5,4,3,4)
val res=numbers.distinct
zip 将两个列表合并为一个一一对应的元组列表,当两个列表长度不相等时,以长度较短的列表为基准
val list1 = List(1,2,3,4,5)
val list2 = List(6,7,8,9,10,11)
val res=list1.zip(list2)

归约列表

把列表收缩为单个值,称为归约列表。

数学归约操作:

操作名 描述 示例
max 查找列表中的最大值
val list = List(21,59,26)
val res=list.max
min 查找列表中的最小值
val list = List(21,59,26)
val res=list.min
profuct 将列表中的数相乘
val list = List(2,4,6)
val res=list.product
sum 对列表中的数求和
val list = List(2,4,6)
val res=list.sum

布尔归约操作:

操作名 描述 示例
contains 检查列表中是否包含这个元素
val list = List(34,29,18)
val res=list.contains(29)
exists 检查列表中是否包含满足指定条件的元素,至少有一个满足时返回true,否则返回false
val list = List(24,17,32)
val res=list.exists(_<18)
forall 检查列表中是否包含满足指定条件的元素,每一个都满足时返回true,否则返回false
val list = List(24,17,32)
val res=list.forall(_<18)
startWith 检查列表是否以一个给定的列表开头
val list = List(0,4,3)
val res=list.startsWith(List(0))
endsWith 检查列表是否以一个给定的列表结尾
val list = List(0,4,3)
val res=list.endsWith(List(4,3))

通用列表规约操作:

操作名 描述 示例
reduce 给定一个归约函数,从列表中的第一个元素开始归约列表
val list = List(1,2,3,4,5)
val res1 = list.reduce(_-_)
reduceLeft 给定一个归约函数,从列表中的第一个元素开始从左到右归约列表(等于reduce)
val res2 = list.reduceLeft(_-_)
reduceRight 给定一个归约函数,从列表中的第一个元素开始从右到左归约列表
val res3 = list.reduceRight(_-_)
fold 给定起始值和归约函数来归约列表,相当于有初始值的reduce
val res4 = list.fold(10)(_-_)
foldLeft 给定起始值和归约函数从左到右归约列表(等于fold)
val res5 = list.foldLeft(10)(_-_)
foldRight 给定起始值和归约函数从右到左归约列表,相当于有初始值的reduceRight
val res6 = list.foldRight(10)(_-_)
scan 给定一个起始值和归约函数,返回各个累加值的一个列表(相当于显示过程的fold)
val res7 = list.scan(0)(_-_)
scanLeft 给定一个起始值和归约函数,从左到右返回各个累加值的一个列表(等于scan)
val res8 = list.scanRight(0)(_-_)
scanRight 给定一个起始值和归约函数,从右到左返回各个累加值的一个列表(相当于显示过程的foldRight)
l res9 = list.scanRight(0)(_-_)

Set

一个不可变的无序集合,只包含不重复的唯一元素,不过其工作与List类似。

val unique = Set(10,20,30,20,20,10)
	 
val sum = unique.reduce( (a: Int,b:Int) => a+b )

Map

一个不可变的键/值库,在其他语言中也称为散列映射、字典或关联数组。在Map中,值按一个给定的唯一键存储,可以使用这个键来获取相应的值

举例:

val colorMap = Map("red" -> 0xFF0000,("green",0xFF00),"blue" -> 0xFF)    //可以使用键值对或二元组的形式来定义

println(colorMap)

获取value值,有两种方法:

一种是以函数的方式调用map,把key当作参数,可以直接获得具体的value值

另一种可以像Java中一样使用get()方法,把key当作参数,但是返回的是一元集合的形式


可变Map 只能按下标取元素

不可变Map只能按key值取元素

val redRGB = colorMap("red")

val greenRGB=colorMap.get("red")
    
println(redRGB)
    
println(greenRGB)

同样地,map也可以使用for循环迭代。

for(c <- colorMap){
    println(c)
}

判断map中是否包含某个key可以使用contains()方法

val hasWhite = colorMap.contains("white")
    
println(hasWhite)

转换集合:

操作名 描述 示例
toBuffer 将不可变的集合转换为可变的集合
val list = List(1,2,3,4,5)
val res=list.toBuffer
res.append(6)
toList 将集合转换为List
val map = Map("a" -> 1,"b" -> 2)
val list=map.toList
toMap 将长度为2的元组的集合转化为Map
val set = Set(1 -> true,3 -> false)
val map=set.toMap
toSet 将集合转换为Set
val list = List(2,5,5,3,2)
val set = list.toSet
toString 将集合转成String,包括集合的类型
val list = List(1,2,3,4,5)
val str=list.toString()
mkString 使用给定的分隔符将集合呈现为String,还可以指定字符串的开头和结尾
val list = List(1,2,3,4,5)
val str = list.mkString("[","|","]")

猜你喜欢

转载自blog.csdn.net/hr786250678/article/details/86360179