Scala入门(四)集合框架

  • 数组
  • 序列 List
  • 映射 Map
  • 集 Set
  • Option

Scala的集合有三大类:序列Seq、集Set、映射Map,实现Iterable特质(类似接口)
集合有可变(mutable)和不可变(immutable)两种类型;
默认是不可变 scala.collection.immutable ;如果需要使用可变集合,手动导包 scala.collection.mutable
immutable 类型集合初始化后内容不能改变,而val 指的是变量的引用不可变

集合框架

1. 数组

1.1 定长数组和变长数组

定长数组: Array 长度不可变,内容可变
变长数组: ArrayBuffer 长度,内容均可变

创建定长数组:

val arr1 = Array[Int](1,2,3,45)   //类型可省略
val arr2 = new Array[Int](10)   //需指定数组类型和长度

取值与赋值,下表从0开始:

arr1(0)  //取值
arr1(0)=100 //赋值

打印数组:

println(arr1)  //打印hashcode
println(arr1.toBuffer) //转换成数组缓冲(变长数组),可查看其内容

创建变长数组:

import scala.collection.mutable.ArrayBuffer  //先导包
val ab = ArrayBuffer[Int](1,3,4)
val ab = new ArrayBuffer[Int]()

变长数组操作:

ab += 1  //+=尾部追加元素
ab += (2, 3, 4, 5)  //追加多个元素
ab -= (3, 4)
ab ++= Array(6, 7)   //追加一个数组++=
ab ++= ArrayBuffer(8,9)   //追加一个数组缓冲
ab --= Array(6, 7)   //减少一个数组++=
ab.insert(0, -1, 0)   //在第一个参数位置处插入后面的所有可变参数
ab.remove(8, 2)   //删除第一个参数后的2个元素
ab.clear()   // 清空
println(ab)  //打印

1.2 数组转换

Array(1,2,3,4).toBuffer   //定长数组转换成变长数组
ArrayBuffer[Int](1,2,3,4).toArray  //变长数组转换成定长数组

1.3 常用方法

val newArr=for(e <- arr) yield e*2 //使用yield生成一个新数组
arr.map(_*2) //遍历
arr.sum  //求和
arr.max  //求最大值
arr.sorted  //排序
arr.reverse //反转
arr.slice(1,4)  //从第一个参数位置(包含)开始到第二个参数位置(不包含)

序列 List

不可变List : 长度,内容 都不可变 ; Array内容可变
可变ListBuffer : 长度,内容都可变
创建不可变List:

val list1= List[Int](1,2,3)
val list2 = 9::5::2::Nil // ::操作符是右结合的,该操作符就是将给定的头和尾创建一个新的列表

不可变列表的连接:

val lst2 = 0 :: lst1  // 0插入到lst1之前,产生一个新的集合
val lst4 = 0 +: lst1 // 0插入到lst1之前,产生一个新的集合
val lst6 = lst1 :+ 3 //3插入到lst1后面,产生一个新的集合
 val lst7 = lst1 ++ lst0   //将2个list合并成一个新的List
val lst8 = lst1 ++: lst0   //将2个list合并成一个新的List
val lst9 = lst1 ::: lst0   //将2个list合并成一个新的List
val lst10 = List.concat(lst1,lst0)   //将2个list合并成一个新的List

其他方法:

lst1.reverse   // 列表反转
lst1.head   // 列表头元素
lst1.tail   // 列表的尾列表

创建可变List:

import scala.collection.mutable._  //导包
val lb1 = ListBuffer[Int]() // 创建的同时可赋初值
val lb2 = new ListBuffer[Int]() // 类型必须显示指定

可变list操作:

lst1 += (4,6)//向lst1中追加元素,注意:没有生成新的集合
lst1.append(5)
val lst2 = lst0 ++ lst1  // lst0和lst1合并,生成一个新集合
lst0 ++= lst1  // lst1追加到lst0中,注意:没有生成新的集合
val lst3 = lst0 :+ 5  //将元素追加到lst0的后面生成一个新的集合
val lst4 = 5 +: lst0  //将元素追加到lst0的前面
lb2 -= (1,3)   // 去除元素
lb2 --= List(7,9)  // 去除元素
lb2.remove(1,2) //去除元素 第一个参数是下标,第二个参数的个数
lb2.isEmpty()  // 判断集合是否为空 

映射Map

不可变Map创建:

val mp1 = Map(("a",1),("b",2))
val mp2 = Map("a"->1,"b"->2)

不可变Map添加元素:

val mp3 = mp2+("c"->1) 

可变Map创建:

import scala.collection.mutable  //导包
val mp4 = new mutable.HashMap[String,Int]()
val mp5 = mutable.Map[String,Int]()

可变Map添加元素:

mp4 += ("a"->1, "b"->2)
mp4+= (("c",3))
mp4.put("d",4)
mp4("e")=5 

获取映射值:

mp4.contains(“a”)  //返回值 Boolean
mp4(“b”)  //获取key为b的value
mp4.get(“c”)  
mp4.getOrElse(“f”,6)  //获取key为f的value,如果key不存在,则默认显示为6

修改映射值:

m1.updated("b",22)  // 如果是不可变的Map,那么会生成一个新的map集合

删除元素:

m1 -= ("a")
m1.remove("a")
m1 -= ("a","b")  //删除多个key

遍历:

for(i <- mp) println(i)  
for((k,v) <- mp){println(k)}  
for((_,v) <- mp){println(v)}  
for((k,v) <- mp) yield (v,k)  //交换kv
mp.map(x=>(x._2,x._1))   //交换kv
mp.map(x=>x.swap)   //交换kv

获取keys和values:

m.keys
m.keySet
m.values

合并map:

val map1= Map("a" ->1,"b" -> 2)
val map2= Map("a" -> 3,"c" -> 4)
var map= map1++ map2    // Map("a" ->3,"b" -> 2,"c"->4) 合并时会虑重 去除键相同的元素,并且以新的值代替

Set

不可变Set:长度和值都不可变,元素不可重复
不可变Set创建:

val set1 = Set (1,2,3)

不可变Set添加删除:

val s2: Set[Int] = set1 + (4,5)
set1 - (1)

可变Set:长度和值均可改变,元素不重复
可变Set创建:

 import scala.collection.mutable.Set // 可以在任何地方引入 可变集合
val mSet = new mutable.HashSet[Int]()
val mutableSet = Set(1,2,3)

可变Set添加和删除:

mutableSet.add(4)
mutableSet += 5
mutableSet += (5,6)
mutableSet ++= Set(7,8)
mutableSet -= 9
mutableSet -= (9,10)
mutableSet.remove(1)  //移除的是1元素

可变Set转换成不可变Set:

val another = mutableSet.toSet

Option

Option 表示可以有值,也可能没有值的返回类型,有两个子类,
Some,有值的结果 Some(值) ,多例,样例类, 想要获取值,使用 get方法
None,没有值,单例,样例对象

val rv: Option[Int] = mp.get("d")  //可能有值,也可能无值
val r1 = rv.get  //如果rv为None,则会出现异常
val r2 = mp.getOrElse("d", -1)  //推荐使用,如果无值,返回默认值-1

集合的常用方法

map:遍历
filter:过滤满足条件的所有元素,返回集合
find:过滤出满足条件的一个元素,返回option
sorted:按元素升序排序
sortBy:按指定条件排序
sortWith:接收参数,进行比较
mapValues:类似map,只处理value
groupBy:按照指定条件分组
grouped:按元素个数进行分组
count:统计满足条件的元素个数
reduce:元素归并 reduceRight   val arr=Array("aa","bb","cc","dd"); arr.reduce(_ + _)   //aabbccdd
        参数是一个函数,该函数有两个参数  累加值 元素值
fold:两个参数 第一个参数是默认值,第二个参数是一个函数,该函数有两个参数,累加值 函数值
intersect :交集    union:并集    diff:差集
distinct:元素去重
mkString:所有元素拼成字符串   mkString(分隔符)
take(n):获取集合中前几个元素
slice(from ,util) 截取元素
aggregate:聚合

小练习

    println("计算一个Array[Double]数组的平均值")
    val arr1 = Array[Double](1, 2, 3, 4, 5)
    val res1: Double = arr1.sum / arr1.length
    println(res1)

    println("编写一个函数或方法,返回数组中最小值和最大值的对偶  (元组)")

    def test2(arr: Array[Double]) = (arr.max, arr.min)

    println(test2(arr1))
    val test22 = (arr: Array[Double]) => (arr.max, arr.min)
    println(test22(arr1))

    println("编写一个函数或方法,getValues(values: Array[lnt],v:Int),返回数组中小于v、等于v和大于v的元素个数,要求三个值一起返回")
    val getValues = (values: Array[Double], v: Double) => {
      val less = values.count(t => t - v < 0)
      val more = values.count(t => t - v > 0)
      val equal = values.count(t => t - v == 0)
      (less, more, equal)
    }
    println(getValues(arr1, 1))


    println("数组反转 Array(1,2,3,5,6,7,9)  2 1 5 3 7 6 9")
    val arr2 = Array(1, 2, 3, 5, 6, 7, 9)
    val iterator: Iterator[Array[Int]] = arr2.grouped(2)
    val res2: Iterator[Int] = iterator.flatMap(t => t.reverse)
    val res3: Array[Int] = res2.toArray
    println(res3.toBuffer)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容