数组分为不可变长数组(Array) 和可变长数组(ArrayBuffer) 。 如字面意思,前者长度不可变, 已经写死了, 后者长度可变。注:只是长度不可变, 但是对应角标元素可变 。
/**
* 在Scala中,数组分为不可变长数组(在immutable包下)和可变长数组 (在mutable下)
* 不可变长数组:长度不可变,角标元素值可变
* 可变长数组:长度可变,角标元素值可变
*/
不可变长数组(Array)
在Scala中, Array代表的含义与Java中类似, 也是长度不可改变的数组。 此外,由于Scala与Java都是运行在JVM中, 双方可以互相调用, 因此Scala数组的底层实际上是Java数组。 例如字符串数组在底层就是Java的String[], 整数数组在底层就是Java的Int[] 。
/**
* 不可变长数组
*/
//[Int]相当于java中的泛型,起到元素类型保护的作用
val arr1 = Array[Int](1, 2, 3, 4)
//如果一个数组中,有多个不同值类型的元素,那么这个数组的类型是这些元素类型的公共父类型Any
val arr2: Array[Any] = Array("true", false, 100, 'a')
//定义了一个数组,长度为5,初始值与泛型的初始值一致,也就是0
val arr3 = new Array[Int](5)
// println(arr3.toBuffer)//ArrayBuffer(0, 0, 0, 0, 0)
//定义了一个数组,长度为1,值为5
val arr4 = Array(5)
// println(arr4.toBuffer)//ArrayBuffer(5)
arr1(0) = 100
// println(arr1.toBuffer)
//++ 运算符:将两个数组合并成一个新的数组,原数组不改变
val arr5 = arr1 ++ arr2
// println(arr5.toBuffer)
可变长数组(ArrayBuffer)
在Scala中, 如果需要类似于Java中的ArrayList这种长度可变的集合类, 则可以使用ArrayBuffer。
如果不想每次都使用全限定名, 则可以预先导入ArrayBuffer类import scala.collection.mutable.ArrayBuffer
// 使用ArrayBuffer()的方式可以创建一个空的ArrayBuffer
val b = ArrayBuffer[Int]()
// 使用++=操作符, 可以添加其他集合中的所有元素
/**
* 可变数组
*/
val arr6 = ArrayBuffer[Int]()
//+= 添加一个元素
arr6 += (1)
arr6 += (2)
//++= 添加一个数组
arr6 ++= Array(3, 4, 5)
arr6 ++= ArrayBuffer(6, 7, 8)
//添加多个元素
arr6 append (9, 10)
//移除数组的一个元素值
arr6 -= 1
arr6 -= 10
//移除一个数组
arr6 --= Array(3, 5, 7)
//根据下标移除
arr6 remove (0)
//从角标开始移除几个元素
arr6 remove (0, 2)
数组常见操作max,min,sum,mkString
/**
* 数组常用方法
*/
val arr = Array(1,2,3,4,5,6)
// println(arr.max)
// println(arr.min)
// println(arr.mkString)//123456
// println(arr.mkString("|"))//1|2|3|4|5|6
// println(arr.mkString("[", "|", "]"))//[1|2|3|4|5|6]
// println(arr.reverse.toBuffer)//Array(1,2,3,4,5,6)-->Array(6,5,4,3,2,1)
for ,foreach
数组的转换操作
flatMap , map , flatten , filter , sortBy.... /**
* 数组的转换操作
*/
val arr7 = Array[Int](8,7,9,10,12)
// arr7.map((x:Int)=> x*2).sortBy((x:Int)=>x).reverse.foreach((x:Int)=> println(x))
// arr7.map(_ * 2).sortBy(x => x).reverse.foreach(println(_))
val strArr = Array[String]("hello world","hello scala")
// strArr.map((x:String) => {
// val split = x.split(" ")
// split
// }).flatten.foreach(println(_))
// strArr.map(_.split(" ")).flatten.foreach(println(_))
// strArr.flatMap((x:String)=> x.split(" ")).map(x => (x,1)).foreach(println(_))
strArr.flatMap(_.split(" ")).map((_,1)).foreach(println(_))
序列分为不可变长序列(List) 和可变长序列(ListBuffer)。不可变集合中添加新元素, 会生成一个新集合, 和不可变集合并不矛盾。给集合中添加元素一般都是从集合头部添加, 或者从集合尾部添加。
/**
* List序列
* 分为变长和不可变长序列,底层是链表
* 特点:有序,可重复,增删快,查询慢
* 不可变长序列:长度和角标都不可变
*/
/**
* 不可变长序列
*/
val list1 = List(1, 2, 3, 4)
//++ 连接两个list,形成一个新的list,原先的list不改变
val list2 = list1 ++ List(6, 7, 8)
// println(list2.toBuffer)//ArrayBuffer(1, 2, 3, 4, 6, 7, 8)
/**
* 变长序列
*/
val lb0 = ListBuffer[Int](1, 2, 3, 4)
// += 添加元素
lb0 += 4
// ++= 添加一个List或ListBuffer
lb0 ++= List(5, 6, 7)
//append 添加多个元素
lb0.append(8, 9, 10)
// println(lb0.toBuffer) //ArrayBuffer(1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10)
//对应移除
lb0 -= 4
lb0 --= List(5, 6, 7)
lb0 remove (0)
// println(lb0.toBuffer) //ArrayBuffer(2, 3, 4, 8, 9, 10)
lb0 remove (0, 2)
// println(lb0.toBuffer) //ArrayBuffer(4, 8, 9, 10)
/**
* list头部添加元素
*/
val list3 = List(4,5,6)
//并不是将元素添加到list3中,而是list3和(1,2,3)进行了合并形成了一个新的list
//注意,(1,2,3)作为一个整体和list3进行合并
var newList = list3 .:: (1,2,3)//List((1,2,3), 4, 5, 6)
newList = list3.+: (1,2,3)//List((1,2,3), 4, 5, 6)
newList = (1,2,3) :: list3//List((1,2,3), 4, 5, 6)
newList = (1,2,3) +: list3//List((1,2,3), 4, 5, 6)
//这里是将1,2,3元素
newList = List(1,2,3) ++ list3//List(1, 2, 3, 4, 5, 6)
// println(newList)
/**
* list尾部添加元素
*/
val list4 = List(1,2,3)
//将(7,8,9)作为一个整体与list4进行合并,插入到list4尾部,形成一个新的list
var newList4 = list4.:+(7,8,9)//List(1, 2, 3, (7,8,9))
//将7,8,9与list4合并,插入到list4尾部,形成一个新的list
newList4 = list4 ++ List(7,8,9)//List(1, 2, 3, 7, 8, 9)
// println(newList4)
/**
* 序列的常用操作方法
*/
val list5 = List(1,2,3,4,5)
//求和
println(list5.sum)
//最大值
println(list5.max)
//最小值
println(list5.min)
//第一个元素
println(list5.head)//1
//最后一个元素
println(list5.last)//5
//反转序列,形成一个新list,原list不变
println(list5.reverse)//List(5, 4, 3, 2, 1)
//拼接
println(list5.mkString)//12345
println(list5.mkString("|"))//1|2|3|4|5
println(list5.mkString("[", "|", "]"))//[1|2|3|4|5]
/**
* 转换操作
*/
val list6 = List(3,5,1,2,2,3,5,2)
list6.map(_*2).filter(x => x>3).sortBy(x => x).distinct.reverse.foreach(println(_))
也分为可变长和不可变长集合,特点:无序,不重复。元素虽然无放入顺序, 但是元素在set中的位置是由该元素的HashCode决定的, 其位置其实是固定的。
/**
* 不可变长set集合
*/
val set1 = Set(1,2,4)
val set2 = set1 ++ Set(4,5,6)
println(set2)//Set(5, 1, 6, 2, 4)
/**
* 可变长set集合
*/
val set3 = scala.collection.mutable.Set(1,2,3)
//+= 添加元素
set3 += 4
set3 += 5
// ++= 后面跟一个set集合
set3 ++= Set(4,5,6)
set3 add(7)
println(set3)//Set(1, 5, 2, 6, 3, 7, 4)
set3 -= 3
set3 --= Set(1,2,3)
println(set3)//Set(5, 6, 7, 4)
/**
* 常用操作
*/
println(set3.mkString("|"))
println(set3.size)
println(set3.head)
println(set3.last)
println(set3.max)
/**
* 转换操作
*/
set3.map(_ * 2).filter(_ < 5).foreach(println(_))
映射是K/V对偶的集合, 对偶是元组最简单的形式, 元组可以封装多个不同类型的值, 注意元组的角标是从1 开始的 。
//定义一个元组
val t1 = ("小明", "男", 23)
//元组的角标是从1开始
println(t1._1 + ":" + t1._2 + "-" + t1._3)
//只有两个元素组成的元组,称为对偶元组(key-value)
val tuple2 = ("id", 124)
println(tuple2._1 + ":" + tuple2._2)
//可以将元组的单个元素单独赋值给对应的变量
val tuple3, (name, age, sex) = ("张三", 12, "男")
println(tuple3)
println(name)
println(age)
println(sex)
//数组的拉链操作转换成元组,按角标序列一一对应
val arr1 = Array("a", "b", "c")
val arr2 = Array("A", "B", "C")
val tuple = arr1 zip arr2
println(tuple.toBuffer) //ArrayBuffer((a,A), (b,B), (c,C))
映射就是java里面的map, 里面存放的是k-v类型的数据, 底层是hash表。scala默认导入的是imutable包下面的Map映射, 它是不可变的(长度和对应的值都是不可变的)。
构建映射
构建映射有两种方式, 一种是箭头 ->, 一种是元组()
/**
* 不可变长映射
*/
//使用元组的形式定义map
val map1 = Map(("a", "A"), ("b", "B"))
//使用箭头的形式
val map2 = Map("a" -> "A", "b" -> "B", "c" -> "C")
//两者混合的形式
val map3 = Map(("a" -> "A"), "b" -> "B")
//++ 合并两个map,形成一个新的map
val map4 = map1 ++ map2
// println(map4)//Map(a -> A, b -> B, c -> C)
/**
* 可变长Map映射
*/
val map5 = scala.collection.mutable.Map("a" -> "A")
map5 put ("b", "B")
map5 += ("c" -> "C", "d" -> "D")
map5 += (("e", "E"), ("f" -> "F"))
map5 ++= Map("j" -> "J")
// println(map5)//Map(e -> E, b -> B, j -> J, d -> D, a -> A, c -> C, f -> F)
//移除map中的key
map5 -= "a"
map5 --= Set("b", "c")
map5 remove ("d")
// println(map5)//Map(e -> E, j -> J, f -> F)
/**
* 常用操作方法
*/
val map6 = Map("a" -> "A", "b" -> "B", "c" -> "C", "d" -> "D")
//contains 判断一个key是否存在,存在返回true,否则返回false
println(map6.contains("a"))
//获取key对应的值,如果通过Map("key")获取key对应的值,先要判断key是否存在
if (map6.contains("a")) println(map6("a"))
//get 也可以获取key对应的值,返回一个option类型的对象。option有两个子类,Some和None,如果有key,则返回Some(Some对象中封装了key对应的值,
//可以通过Some的get方法获取);如果没有,则返回None对象
println(map6.get("b")) //Some(B)
println(map6.get("e")) //None
val v1: Option[String] = map6.get("d")
if (!v1.isEmpty) println(v1.get) else println(v1)
//getOrElse 获取key对应的value,如果key不存在,返回默认值
val v2 = map6.getOrElse("f", 0)
println(v2) //0
LinkedHashMap、SortedMap
/**
* LinkedHashMap:插入有序,按照插入顺序排序,底层是链表结构
*/
val map7 = scala.collection.mutable.LinkedHashMap[String, String]()
map7 += ("a" -> "A")
map7 += ("c" -> "C")
map7 += ("b" -> "B")
map7 += ("2" -> "123")
map7 += ("1" -> "123")
// println(map7)//Map(a -> A, c -> C, b -> B, 2 -> 123, 1 -> 123)
/**
* SortedMap 可以对key进行自动字典排序
*/
val map8 = scala.collection.mutable.SortedMap[String, String]()
map8 += ("a" -> "A")
map8 += ("c" -> "C")
map8 += ("b" -> "B")
map8 += ("2" -> "123")
map8 += ("1" -> "123")
// println(map8)//TreeMap(1 -> 123, 2 -> 123, a -> A, b -> B, c -> C)