12_Scala_数据结构上_Array_Tuple_List_Queue_Map_Set
Scala 集合都扩展自Iterable特质
三大类:序列Seq 集Set 映射Map 都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)两种类型
scala.collection.immutable (不可变) 1 可以安全的并发访问 2 不懂动态扩展 类似Java数组
scala.collection.mutable (可变) 1 本身可变,类似arrayList 动态扩展
1 数组 构建
new Array[泛型](长度) 中括号泛型,小括号访问 arr(1)
apply方法创建数组对象 val arr1 = Array(1, 2)
object ArrayDemo01 {
def main(args: Array[String]): Unit = {
// 方式一 数组等同于Java中的数组,中括号的类型就是数组的类型
// [Int] 表示泛型,即该数组中,只能存放Int
// [Any] 表示 该数组可以存放任意类型
val a1 = new Array[Any](3) //底层 int[] a1 = new int[4]
a1(0) =10
a1(1) ="alex"
a1(2) = true
for( i <- a1){
println(i)
}
val a2 = a1.mkString(" ")
//方式二 直接赋值 object Array 的apply
//1. 使用的是 object Array 的apply
//2. 直接初始化数组,因为包括了int和 "", 数组的泛型就Any
var aa2 = Array(1, 2, "bob")
aa2(1) = "alex"
println(aa2.length)
//可以使用我们传统的方式遍历,使用下标的方式遍历
for (index <- 0 until aa2.length) {
printf("arr02[%d]=%s", index , aa2(index) + "\t")
}
println()
println("*****")
// 变长数组 必须指定泛型 [类型] (初始值,可有可无)
val abuffer = ArrayBuffer[Any](10, 20, 30) // append 内容后,底层是创建了一个新地址 返回给 val
println(abuffer.length + " " + abuffer.hashCode()) //3 573686093
// for (index <- 0 until abuffer.length ){
// println(abuffer(index))
// }
// abuffer.append("alex","bob") //追加数据,过时了
// abuffer.appendAll("alex")
abuffer.appendAll(Array(50, 60,70)) //appendAll(要求传入一个 iterable实现类)
println(abuffer.length + " " + abuffer.hashCode())
abuffer(1) = 200 //修改
abuffer.remove(0) //删除,是根据下标索引 来删除
abuffer.remove(0,2) // index int count int
//1. abuffer.toArray 调用 abuffer的方法 toArray 将 ArrayBuffer ---> Array
//2. arr2本身没有任何变化
val array = abuffer.toArray
// Array ---> ArrayBuffer array 本身没有变化 返回一个新的 ArrayBuffer
val abuffer_new = array.toBuffer
// 多维数组
val arrDim = Array.ofDim[Int](2, 5)
arrDim(1)(1) =10
// 遍历1
//0 0 0 0 0
//0 10 0 0 0
for (i <- arrDim){
for (j <- i){
println(j + "\t")
}
println()
}
// 遍历2
for (i <- 0 to arrDim.length -1 ){
for (j <- 0 to arrDim(i).length -1){
printf("arr[%d][%d]=%d\t", i, j, arrDim(i)(j))
}
println()
}
}}
2 Tuple-元组 最大只能有22个元素 可以存放各种相同或不同类型的数据 (元祖类型取决于后面放多少个元素)
访问元组中的数据,可以采用顺序号(_顺序号),也可以通过索引(productElement)
object TupleTest {
def main(args: Array[String]): Unit = {
//灵活
var tup1 = (10, 20, 30, "hello", 40) //10 访问元祖第一个元素 从1开始
println(tup1) //(10,20,30,hello,40)
// 1从1开始 访问元组的第一个元素
println(tup1._1) //10 访问元祖第一个元素, 从0开始
println(tup1._3) //30
/*
override def productElement(n : scala.Int) : scala.Any = { /* compiled code */ }
def _1 : T1
def _2 : T2
def _3 : T3
*/
// 0从0开始 访问元组的第一个元素
println(tup1.productElement(0)) //10
println(tup1.productElement(2)) //30
//遍历 需要迭代器
for (i <- tup1.productIterator) { //用迭代器实现的,移动的指针
println(i)
} }
}
3 List
在Java中List是一个接口,真正存放数据是ArrayList,
Scala的List可以存数据,默认情况下Scala的List是不可变的,List属于序列Seq (LinearSeq)。
val List = scala.collection.immutable.List # object List extends SeqFactory[List]
object ListTest1 {
def main(args: Array[String]): Unit = {
//1. 在默认情况下 List 是scala.collection.immutable.List,即不可变
//2. 在scala中,List就是不可变的,如需要使用可变的List,则使用ListBuffer
//3. List 在 package object scala 做了 val List = scala.collection.immutable.List
//4. val Nil = scala.collection.immutable.Nil // List()
val list01 = List(10,20,"alex")
val list02 = Nil //List()
println(list01 + " " + list02)
// 追加元素
// :+ 表示在列表的最后增加数据
val list04 = list01:+ 40
// +: 表示在列表的开头增加数据
val list05 = 50 +: list04
println(list04 + " " + list05) //List(10, 20, alex, 40) List(50, 10, 20, alex, 40)
//:: 运算符的使用 --> 逐步添加
val list_a = List(1,2,3)
val list_b = 4::5::6:: list_a
println(list_b) //List(4, 5, 6, 1, 2, 3)
val list_b2 =4::5::6:: list_a :: Nil //List(4, 5, 6, List(1,2,3)) List(1,2,3) 是个整体
val List_c = List(10,20,30)
val list_d = 50::40::List_c:::Nil
// ::: 拆开后加入List 里面 (集合每个元素添加到新集合)
println(list_d) //List(50, 40, 10, 20, 30)
}
}
object ListBufferTest {
def main(args: Array[String]): Unit = {
//创建ListBuffer apply
val lst0 = ListBuffer[Int](10,20,30)
//动态的增加元素,lst1就会变化, 增加一个一个的元素
val lst1 = new ListBuffer[Int] //空的ListBuffer
// 两种添加方式 1 运算符 += 2 方法 append
lst1 += 40// lst1 (40)
lst1.append(50)// list1(40,50)
//一个集合加到另个集合 list1是被加的,list0有变化
lst0 ++= lst1 // lst0 (10, 20, 30, 40, 50)
println("lst0=" + lst0) //ListBuffer(10, 20, 30, 40, 50)
val lst2 = lst0 ++ lst1 //返回新的ListBuffer(10, 20, 30, 40, 50, 40, 50) lst0 不变
println("lst2=" + lst2)
val lst3 = lst0 :+ 60 // lst0不变 返回新的 ListBuffer(10, 20, 30, 40, 50, 60)
println("lst3=" + lst3)
println("=====删除=======")
println("lst1=" + lst1)
lst1.remove(1) // 表示将下标为1的元素删除 , 角标从0开始
for (item <- lst1) { // list1(40,50)
println("item=" + item) //40
}}}
4 Queue
有序列表,在底层可以用数组或是链表来实现。
先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
scala.collection.mutable.Queue (常用) 和 scala.collection.immutable.Queue
object QueueTest {
def main(args: Array[String]): Unit = {
// 创建 [泛型]
val queue1 = new mutable.Queue[Any]()
// 添加元素方式
//1 运算符方式 + 添加单个元素
queue1 += 20
//2 ++= List() 默认值list里的元素加入到 queue的最后面
queue1 ++= List(30,40)
println(queue1) //Queue(20, 30, 40)
//3 += List() 作为一个整体加入队列 要求queue类型是any
queue1 += List(10,0)
println(queue1) //Queue(20, 30, 40, List(10, 0))
// 出队列, 默认从队首取数据 取出元素(弹出去) 自身变化,
val qvalue = queue1.dequeue()
println(qvalue + " queue1: " + queue1) //20 queue1: Queue(30, 40, List(10, 0))
// 入队列 默认加入队尾 自身变化
queue1.enqueue(100,200)
println( " queue1: " + queue1) // queue1: Queue(30, 40, List(10, 0), 100, 200)
//队列 Queue-返回队列的元素 查询类
//1. 获取队列的第一个元素
println(queue1.head) // 对q1没有任何影响 30
//2. 获取队列的最后一个元素
println(queue1.last) // 对q1没有任何影响 200
//3. 取出队尾的数据 ,即:返回除了第一个以外剩余的元素,可以级联使用
println(queue1.tail) // Queue(40, List(10, 0), 100, 200)
println(queue1.tail.tail.tail.tail) // Queue(200)
}
}
5 Map
HashMap 是一个散列表(数组+链表),它存储的内容是键值对(key-value)映射,Java中的HashMap是无序的,key不能重复
Scala中的Map 散列表(key 唯一后才能散列) 存键值对(key-value)映射
scala.collection.mutable.Map 和 scala.collection.immutable.Map 是有序的
object MapTest {
def main(args: Array[String]): Unit = {
//方式1-构造不可变映射
//1.默认Map是 immutable.Map 无法操作 增加/删除
//2.key-value 类型支持Any .在Map的底层,每对key-value是Tuple2
//3.从输出的结果看到,输出顺序和声明顺序一致
val map1 = Map("Alex" -> 30, "BoB" -> 40, "Robbin" -> 28)
println(map1) //Map(Alex -> 30, BoB -> 40, Robbin -> 28)
//方式2-构造可变映射
//1. 可变的map输出顺序和声明顺序不一致
//2. 支持动态变化
// val map2 = mutable.Map("Alex" -> 30, "BoB" -> 40, "Robbin" -> 28)
// println(map2) //HashMap(Alex -> 30, BoB -> 40, Robbin -> 28)
//方式3-创建空的映射 泛型可以是[any, any ]
// val map3 = new mutable.HashMap[Any, Any]()
// println(map3) //HashMap()
//方式4-对偶元组 也可以混用 方式1 方式四 because 底层就是tuple2
val map4 = mutable.Map(("Alex", 35), ("BoB", 45))
println(map4) //HashMap(Alex -> 35, BoB -> 45)
println("************************")
//查询取数据
//方式1-使用map(key) 如果输入key不存在 会抛出异常(java.util.NoSuchElementException: key not found:)
// println(map4("Alice"))
//方式2-使用contains方法检查是否存在key
if (map4.contains("Alex")) {
println("key存在,值=" + map4("Alex"))
} else {println("key不存在:)")}
//方式3 方式3-使用map.get(key).get取值
//1. 如果key存在 map.get(key) 就会返回Some(值) ,然后Some(值).get就可以取出
//2. 如果key不存在 map.get(key) 就会返回None
// println(map4.get("Alice").get) // 抛出异常 NoSuchElementException: None.get
//方式4-使用map4.getOrElse()取值
// println(map4.getOrElse("Alex~~", "默认的值Alexander"))
println("************************")
// 修改操作
val map5 = mutable.Map(("A", 1), ("B", "北京"), ("C", 3))
// 修改 增加 & 修改
map5("A") = 20 // A -> 20
// 修改 += 增加 & 修改
map5 += ("A" -> 100)
println("map5=" + map5) //map5=HashMap(A -> 100, B -> 北京, C -> 3)
// 修改 -= 去除 & 修改
map5 -= ("A", "B", "AAA") // 去除 Key 为 A B AAA的
println("map5=" + map5)
println("************************")
// 遍历操作
// 输出 K V
for ((k,v) <- map1) println(k + " map to " + v)
// 单独输出 Key Values
for (k <- map1.keys ) println(k)
for (v <- map1.values) println(v)
// 用tuple2 形式输出 Key & Value
for (tupleValues <- map1) println("key: " +tupleValues._1 + " values: "+ tupleValues._2 )
}
}
6 集合 (不重复 无顺序) 默认是以哈希集实现
java,HashSet是实现Set<E>接口的一个实体类,数据是以哈希表的形式存放的,存不重复 无序的数据
Scala 使用的是不可变集合,如想使用可变集合,需要引用 scala.collection.mutable.Set 包
object SetTest {
def main(args: Array[String]): Unit = {
// 默认不可变
val set_immut = Set(1, 2, 3)
println(set_immut)
// 可变的 导包 import scala.collection.mutable
val set_mutable = mutable.Set(10, 20, 30)
// 添加操作
set_mutable.add(40) // 方法
set_mutable+=50 // 操作符添加
set_mutable+=(60)
println(set_mutable) //HashSet(50, 20, 40, 10, 60, 30)
// 去除操作
set_mutable -= 10 //操作符形式
set_mutable -= 20
set_mutable.remove( 30) // 调用方法形式 返回值是布尔值
println(set_mutable) //HashSet(50, 40, 60)
// 遍历
for (i <- set_mutable) println(i )
}
}
- 点赞
- 收藏
- 关注作者
评论(0)