Java中不可变集合
不可变集合概念(java为例)
public class ImmutableDemo01ForJava { public static void main(String[] args) { // 1.不可变集合,内容可变,旦数组本身不能动态增长 int []nums = new int[3]; nums[2] = 2; // nums[3] = 1 错误 // 2.可变集合,集合本省能够动态增长ArrayList arrayList = new ArrayList<String>(); arrayList.add("t1"); System.out.println(arrayList.hashCode()); arrayList.add("t2"); System.out.println(arrayList.hashCode()); } }
Scala中的集合
特点
Scala同时支持
不可变集合
和可变集合
,不可变集合可以安全的并发访问
两个主要的包:
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable
Scala默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变(mutable)和不可变(immutable)的版本
Scala的集合有三大类:
序列Seq
、集Set
、映射Map
,所有的集合都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)两种类型.
举个例子
不可变集合: scala不可变集合,就是这个集合本身不能动态变化.(类似java的数组,是不可以动态增长的)
可变集合:可变集合,就是这个集合本身可以动态变化的.(比如:ArrayList,是可以动态增长的)
不可变集合继承层次一栏图
image.png
可变集合继承层次一栏图
image.png
细节
Seq是Java中没有的,List归属于Seq.所以这里的List和Java不一样.
for循环里的
1 to 3
,就是基于IndexSeq下的VectorString
也是属于indexSeq
Queue和Stack
归属于LinearSeq
.即是线性
的,有头有尾
IndexSeq
和LinearSeq
.IndexSeq
是基于索引的序列,LinearSeq
是线性序列
① 数组
Why
Scala同时支持不可变集合
和可变集合
.不可变集合是线程安全的.
队列的应用场景
推荐系统要用户最近浏览的10个商品.
How
学习集合的创建、修改、删除、增加
定长数组-Array
创-方式一-new Array
/** * @author sweetcs */object ArrayDemo01 { def main(args: Array[String]): Unit = { // 默认为零 var arr = new Array[Int](4) println("数组长度=" + arr.length) println("循环遍历数组:") for (item <- arr) { println(item) } arr(3)=1 println("循环遍历数组:") for (item <- arr) { println(item) } } }
创-方式二-Array
/** * @author sweetcs */object ArrayDemo02ForApply { def main(args: Array[String]): Unit = { // 数组元素的类型时Any.一旦定义就不可在更改 var array = Array(1, 2, "beijing") // 数组元素的类型时Int.一旦定义就不可在更改 var arrayOfInts = Array(1,2) for (item <- array) { println(item) } // 传统for循环基于索引遍历 var len = array.length for (i <- 0 until len) { printf("%s\t", array(i)) } } }
变长数组-ArrayBuffer
创-变长数组的增删改查
/** * @author sweetcs */object MutableArrayDemo01 { def main(args: Array[String]): Unit = { val arrayBuffer = ArrayBuffer[Any](2,3,"beijing") println(arrayBuffer(2)) println(arrayBuffer.hashCode()) // 增 arrayBuffer.append(5, 6) println(arrayBuffer.hashCode()) // 删 arrayBuffer.remove(0) // 查 for (item <- arrayBuffer) { print(item + "\t") } } }
定长数组和变长数组的转换
toArray
toBuffer
/** * @author sweetcs */object MutableArrayDemo02ForTranslateImutable { def main(args: Array[String]): Unit = { val arrayBuffer = ArrayBuffer(1,2,"beijing") val array = arrayBuffer.toArray println(array.hashCode(), arrayBuffer.hashCode()) println("遍历不可变数组") for (item <- array) { println(item) } val mutableArray = array.toBuffer mutableArray.append(3) println("遍历mutableArray") for (item <- mutableArray) { println(item) } println("遍历arrayBuffer") for (item <- arrayBuffer) { println(item) } } }
多维数组
语法
// 创建一个3行四列的Double数组val arr = Array.ofDim[Double](3,4)
多维数组Demo
/** * @author sweetcs */object ArrayDemo05ForMultiplyDimArray { def main(args: Array[String]): Unit = { val arr = Array.ofDim[Int](3, 4) // 查 println("查case==========") for (row <- arr) { println(row) for (col <- row) { println(col + "\t") } } println("改case==========") // 改 arr(0)(1) = 3 for (row <- arr) { println(row) for (col <- row) { println(col + "\t") } } } }
Java数组(List)和Scala数组(ArrayBuffer)的互转
Scala->Java
object ArrayDemo06ForScalaArrayToJavaArray { def main(args: Array[String]): Unit = { //创建了ArrayBuffer val arr = ArrayBuffer("1", "2", "3") //下面的import 引入了我们需要的隐式函数【这里就是隐式函数的应用】 //implicit def bufferAsJavaList[A](b : scala.collection.mutable.Buffer[A]) : java.util.List[A] import scala.collection.JavaConversions.bufferAsJavaList // 触发隐式转换 val javaArr = new ProcessBuilder(arr) //返回的是 List<String> val arrList = javaArr.command() println(arrList) //输出 [1, 2, 3] } }
Java->Scala
object ArrayDemo07ForJavaArrayToScalaArray { def main(args: Array[String]): Unit = { val arrList = new java.util.ArrayList[String]() import scala.collection.JavaConversions.asScalaBuffer import scala.collection.mutable // java.util.List ==> Buffer val scalaArr: mutable.Buffer[String] = arrList scalaArr.append("jack") scalaArr.append("tom") println(scalaArr) scalaArr.remove(0) println(scalaArr) // (2,3,jack,tom) } }
What
不可变集合
: 集合本身不能变化,类似于Java里的数组,不是动态增长可变集合
: 集合本身能变化toBuffer的底层实现
又重新new了一个ArrayBuffer,将数据拷贝到这个ArrayBuffer实例中
override def toBuffer[A1 >: A]: mutable.Buffer[A1] = { val result = new mutable.ArrayBuffer[A1](size) copyToBuffer(result) result }
Details
Scala创建的集合几乎所有是
不可变集合
.Scala集合集合的三大类型
Seq\Set\Map
ArrayBuffer是
变长数组
,类似于ArrayList定长数组和变长数组的
相互转换
,返回
的是新数组
,不改变旧数组
② 元组
Why
元组用来解决那些想
把不同的数据类型
放在一起的需求.元组可以理解为一个容器, 可以存放各种相同或不同类型的数据.
How
元组语法
使用小括号标识元组.
val t = (1,23,"we are")
元组DEMO
元组的创建和元组类型
object TupleDemo01 { def main(args: Array[String]): Unit = { val tuple1 = (1,2,3,4,"hello") println(tuple1, tuple1.getClass) // ((1,2,3,4,hello),class scala.Tuple5) } }
元组访问,序号方式(1开始)、索引方式(0开始)
元组遍历需要使用
迭代器
object TupleDemo02ForAccess { def main(args: Array[String]): Unit = { val tuple = (1, 2, 3, "beijing") println(tuple._1) println(tuple.productElement(0)) println("元组的遍历") // 元组遍历,要用迭代器 for (item <- tuple.productIterator) { println(item) } } }
What
元组的访问-索引方式(0开始)原理
@throws(classOf[IndexOutOfBoundsException]) override def productElement(n: Int) = n match { case 0 => _1 case 1 => _2 case 2 => _3 case 3 => _4 case _ => throw new IndexOutOfBoundsException(n.toString()) }
Details
编译期根据Tuple的数据个数,创建对应元组类型.例如, Tuple5表示这个元组有5个元素.
元组的元素个数
最多是22
个.
③ List
Why
List是Seq的子类,用于按序存放元素.
How
不可变List
list的创建和访问
val list = List(1, 2, 3, "beijing")
list元素的追加方式,使用+:或者:+, 冒号一边为list,返回的是一个新List对象
代码
/** * @author sweetcs */object ListDemo02ForAppendAndReturnNewList { def main(args: Array[String]): Unit = { val list = List(1, 2, 3, "beijing") // 在列表的最后追加 val newList = list :+ 6 // 在列表的头追加 val newList02 = 6 +: list println(s"list hashcode = ${list.hashCode()}, newList = ${newList.hashCode()}, newList02 = ${newList02.hashCode()}") println("newList= " + newList) println("newList02= " + newList02) } }
输出
list hashcode = -1049219423, newList = 173175143, newList02 = -1337286218 newList= List(1, 2, 3, beijing, 6) newList02= List(6, 1, 2, 3, beijing)
::和:::添加集合
object ListDemo02ForAppendAndReturnNewList { def main(args: Array[String]): Unit = { val list = List(1, 2, 3, "beijing") // 在列表的最后追加 val newList = list :+ 6 // 使用::添加元素, 会将一个集合当成一个整体放入集合中. // 使用:::添加元素, 会将一个集合中的元素都依次添加进去 val newList03 = 4 :: 5 :: 6 :: 7 :: list :: Nil println(newList03) val newList04 = 4 :: 5 :: 6 :: 7 :: list ::: Nil println(newList04) } }
可变list-ListBuffer
ListBuffer是可变的list集合, 可以添加, 删除元素,ListBuffer属于序列
object ListDemo03ForListBuffer { def main(args: Array[String]): Unit = { val lst0 = ListBuffer[Int](1, 2, 3) //如何访问 println("lst0(2)=" + lst0(2)) // 输出 lst0(2)= 3 for (item <- lst0) { // 遍历,是有序 println("item=" + item) } //动态的增加元素,lst1就会变化, 增加一个一个的元素 val lst1 = new ListBuffer[Int] //空的ListBuffer lst1 += 4 // lst1 (4) lst1.append(5) // list1(4,5) // lst0 ++= lst1 // lst0 (1, 2, 3,4,5) println("lst0=" + lst0) val lst2 = lst0 ++ lst1 // lst2(1, 2, 3,4,5,4,5) println("lst0=" + lst0) println("lst2=" + lst2) val lst3 = lst0 :+ 5 // lst0 不变 lst3(1, 2, 3,4,5,5) println("lst3=" + lst3) println("=====删除=======") println("lst1=" + lst1) lst1.remove(1) // 表示将下标为1的元素删除 for (item <- lst1) { println("item=" + item) //4 } } }
Details
Scala中的List是能存放元素,Java中的List是一个接口
List属于Seq,默认情况下
创建的List是不可变List实例
List在scala包对象声明的,因此不需要引入其它包也可以使用
val List = scala.collection.immutable.List
:: 运算时,集合对象一定要放置在
最右边
.::: 运算符是将集合中的每一个元素加入到集合中去,并且左右两边都必须是集合.
作者:sixleaves
链接:https://www.jianshu.com/p/bdf90fc486ed