集合概念
- Scala 同时支持不可变集合和可变集合
- 两个主要的包: 不可变集合:scala.collection.immutable 可变集合: scala.collection.mutable
- Scala 默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变(mutable)和不可变(immutable)的版本
- Scala 的集合有三大类:序列 Seq、集 Set、映射 Map,所有的集合都扩展自 Iterable 特质,在 Scala 中集合有可变(mutable)和不可变(immutable)两种类型
不可变集合:scala 不可变集合,就是这个集合本身不能动态变化, 指长度, 其中的值可以改变。(类似java的数组,是不可以动态增长的)
可变集合: 可变集合,就是这个集合本身可以动态变化的, 长度可以变更。(比如:ArrayList , 是可以动态增长的)
//不可变集合类似java的数组
int[] nums = new int[3];
nums[2] = 11; //?
//nums[3] = 90; //,即不能动态的增长
//可变集合
ArrayList al = new ArrayList<String>();
al.add("zs");
al.add("zs2");
System.out.println(al + " " + al.hashCode()); //地址1
al.add("zs3");
System.out.println(al + " " + al.hashCode()); //地址2
不可变集合
1.Set、Map 是 Java 中也有的集合
2.Seq 是 Java 没有的,List 归属到 Seq 了, 因此这里的 List 就和 Java 中的不同
3.for 循环里的1 to 3 ,是 IndexedSeq 下的 Vector
4.String 属于 IndexeSeq
5.经典的数据结构比如 Queue 和 Stack 被归属到 LinearSeq
6. Scala 中的 Map 体系有一个 SortedMap,说明 Scala 的 Map 可以支持排序
7.IndexSeq 和 LinearSeq 的区别
IndexSeq 是通过索引来查找和定位,因此速度快,比如 String 就是一个索引集合,通过索引即可定位
LineaSeq 是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找,它的价值在于应用到一些具体的应用场景 (电商网站, 大数据推荐系统 :最近浏览的10个商品)
可变集合
数组
定长数组
这里的数组等同于Java中的数组,中括号的类型就是数组的类型
val arr1 = new Array[Int](10)
val arr1 = Array(1, 2,"hello")
//集合元素采用小括号赋值,访问 arr1(1) = 7
变长数组
//定义/声明
val arr2 = ArrayBuffer[Int]()
//追加值/元素
arr2.append(7)
//重新赋值
arr2(0) = 7
//删除
arr01.remove(0)
- ArrayBuffer 是变长数组,类似 java 的 ArrayList
- val arr2 = ArrayBuffer[Int]() 也是使用的 apply 方法构建对象
- def append(elems: A*) { appendAll(elems) } 接收的是可变参数.
- 每 append 一次,arr 在底层会重新分配空间,进行扩容,arr2 的内存地址会发生变化,也就成为新的 ArrayBuffer
定变转换
arr1.toBuffer //定长数组转可变数组
arr2.toArray //可变数组转定长数组
arr2.toArray 返回结果是一个定长数组, arr2本身没有变化
arr1.toBuffer返回结果是一个可变数组, arr1本身没有变化
多维数组
//定义
val arr = Array.ofDim[Double](3,4)
var arr2 = Array(Array(1,2), Array(4,5,6), Array("hello","北京"))
arr 是一个二维数组, 有三个元素[一维数组], 每个一维数组存放4个值
//赋值 arr(1)(1) = 11.11
Scala 数组与 Java 的 List 的互转
val arr = ArrayBuffer("1", "2", "3")
import scala.collection.JavaConversions.bufferAsJavaList
//这里的bufferAsJavaList是一个隐式函数
/*
implicit def bufferAsJavaList[A](b : scala.collection.mutable.Buffer[A]): java.util.List
*/
val javaArr = new ProcessBuilder(arr)
val arrList = javaArr.command()
println(arrList) //输出 [1, 2, 3]
Java 的 List 转 Scala 的 Buffer
//asScalaBuffer 是一个隐式转换
/*implicit def asScalaBuffer[A](l : java.util.List[A]) : scala.collection.mutable.Buffer[A]
*/
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable
// java.util.List ==> Buffer
val scalaArr: mutable.Buffer[String] = arrList
scalaArr.append("jack")
println(scalaArr)
元组
元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。
元组中最大只能有 22 个元素, 根据元素个数不同,对应的类型是 Tuple1----Tuple22
Tuple 是一个整体,使用迭代器进行遍历
访问 Tuple 的元素的方式是 tuple._1 .... tuple._3
元组在 scala 推荐使用,java 中没有元组
/* 源码
final case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) extends Product3[T1, T2, T3] {
override def toString() = "(" + _1 + "," + _2 + "," + _3 + ")"
}
*/
//创建元组
val tuple = (1, 2, "hello")
//访问元组
//1. 使用 _顺序号
println(tuple._3) // "hello"
//2. 使用api
println(tuple.productElement(2)) //下标是从0开始计算
//遍历元组[通过迭代器来遍历]
for (i <- tuple.productIterator) {
println("i=" + i)
}