Scala基础之集合(数组)
集合介绍
Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本。
集合可变,不可变的区别
-
Scala默认提供的集合都是不可变。
不可变:增删改 都会返回有个新数组 可变:可增删改
- 可变:
- scala.collection.mutable
hashmap,hashset AraryBuffer,ListBuffer
- 不可变
- scala.collection.immutable
Hashset Hashmap Array List String
不可变数组Array:不可变是指长度不可变
//定义数组,格意义上,数组不是集合,是一种数据结构 val array = new Array[String](3) // 使用集合的伴生对象构建集合,并同时初始化 val array1 = Array(1,2,3,4) val array2 = Array(5,6,7,8) //val array2 = Array.apply(1,2,3,4) //插值 array.update(0,"bb") //插值,或者修改 array(0)="aa" //循环打印 for (elem <- array) {println(elem)}
- 访问(冒号紧邻数组)
val array1 = Array(1,2,3,4) val array2 = Array(5,6,7,8) // 访问 //val ints: Array[Int] = array1.+:(5) // scala中如果运算符是以冒号结尾,那么运算规则为从后向前计算 val ints = 5 +: array1 //val ints1: Array[Int] = array1.:+(5) val ints1 = array1 :+ 5 val ints2 = array1 ++ array2 println(array1 eq ints) println(array1 eq ints1) println(ints eq ints1) // TODO 遍历 println(ints.mkString(",")) println(ints1.mkString(",")) println(ints2.mkString(",")) 结果 false false false 5,1,2,3,4 1,2,3,4,5 1,2,3,4,5,6,7,8
- 数组循环
// foreach方法是一个循环的方法,需要传递一个参数,这个从参数的类型是函数类型 // 函数类型 : Int => U def foreachFunction(num:Int): Unit = { println(num) } //array1.foreach(foreachFunction) //array1.foreach((num:Int)=>{println(num)}) //array1.foreach((num:Int)=>println(num)) //array1.foreach((num)=>println(num)) //array1.foreach(num=>println(num)) 最终一个结果 array1.foreach(println(_))
- 2维数组的创建;数组拼接,填充
// 多维数组 var myMatrix = Array.ofDim[Int](3,3) //myMatrix.foreach(list=>println(list.mkString(","))) val arr1 = Array(1,2,3,4) val arr2 = Array(5,6,7,8) // 合并数组 val arr6: Array[Int] = Array.concat(arr1, arr2) //arr6.foreach(println(_)) // 创建指定范围的数组 val arr7: Array[Int] = Array.range(0,2) arr7.foreach(println) //创建并填充指定数量的数组 val arr8:Array[Int] = Array.fill[Int](5)(-1) arr8.foreach(println)
可变数组
//val buffer = new ArrayBuffer[String]() val buffer = ArrayBuffer("a", "b", "c") buffer.append("a", "b", "c", "d") //ArrayBuffer(a, b, c, a, b, c, d) buffer.appendAll(Array("a", "b", "c")) //ArrayBuffer(a, b, c, a, b, c, d, a, b, c) // buffer.insert(100, "f") IndexOutOfBoundsException //更改 //buffer.update(0, "e") buffer(0) = "e" println(buffer,"**") //删除 //buffer.remove(2) //buffer.remove(2,4) //println(buffer,"@@") val strings: ArrayBuffer[String] = buffer - "e" println(strings,"$$") println(buffer eq strings)
可变<---->不可变转换
val array = Array(1,2,3,4) // 不可变 => 可变 val buffer: mutable.Buffer[Int] = array.toBuffer val buff = ArrayBuffer(1,2,3,4) // 可变 => 不可变 val array1: Array[Int] = buff.toArray // Java集合 <=> Scala集合 array1.foreach(println) import scala.collection.JavaConverters._ //val list = new java.util.ArrayList() //list.asScala.foreach(println) val java: util.List[Int] = List(1, 2, 3, 4).asJava
基本操作
val array = ArrayBuffer(1,2,3,4) // 从集合中获取部分数据 println(array.head) println(array.tail) println(array.tails) println(array.last) println(array.init.foreach(println(_))) // 初始 println(array.inits.foreach(println(_))) // 取前几个 println(array.take(3)) //println(array.reverse.take(2).reverse) println(array.takeRight(2)) println(array.drop(1)) println(array.dropRight(1))
数据操作reduce
val array = ArrayBuffer(1,2,3,4, 5) println(array.sum) println(array.max) println(array.min) println(array.product) // 自定义数据操作的方法 // 集合的数据无论是多少,最基本的数据操作其实都是两两计算。 // map => reduce => 简化,规约(聚合) def reduceFunction(x : Int, y : Int): Int = { x + y } //println(array.reduce(reduceFunction)) //println(array.reduce((x:Int, y:Int)=>{x + y})) //println(array.reduce((x:Int, y:Int)=>x + y)) //println(array.reduce((x, y)=>x + y)) println(array.reduce(_ - _)) // -13 println(array.reduceLeft(_ - _)) // -13 // 【1,2,3,4】 // (((1 + 2) + 3) + 4) // reversed.reduceLeft[B]((x, y) => op(y, x)) // 【1,2,3,4, 5】 // 【5,4,3,2,1】 // 1 - (2 - (3 - (4 - 5))) // 【1,2,3,4】 // (1 - (2 - (3 - 4))) println(array.reduceRight(_ - _)) // 3
数据操作fold
val array = ArrayBuffer(1,2,3,4) val num = 5 // 折叠 println(array.fold(5)(_ - _)) // (((5 - 1) - 2) - 3) - 4 //println(array.foldLeft(5)(_ - _)) // reversed.foldLeft(z)((x, y) => op(y, x)) // 【1,2,3,4】 // 【4,3,2,1】 // 1 - (2 - (3 - (4 - 5))) println(array.foldRight(5)(_ - _)) // 5 ,5-1 ,5-1-2,5-1-2-3,5-1-2-3-4 println(array.scan(5)(_ - _)) // 1,2,3,4,5=>reserve(5,4-5,3-(4-5),2-(3-(4-5)).... println(array.scanRight(5)(_-_))
数据操作 map
// 功能函数:由集合对象提供函数执行自定义的功能 // 1. map => 映射(转换) => K->V // a => b // map方法需要传递一个参数,这个参数的类型为函数类型: Int => B def mapFunction( num:Int ): Int = { num * 2 } //println(array.map(mapFunction)) // println(array.map( // (num:Int) => { // num * 2 // } // )) println(array.map(_*2))
数据操作 flatmap
// val array = ArrayBuffer( // ArrayBuffer( // ArrayBuffer(1,2),ArrayBuffer(5,6) // ), ArrayBuffer( // ArrayBuffer(3,4),ArrayBuffer(7,8) // ) // ) //println(array.length) // 将整体拆分成个体的操作,称之为扁平化 // 扁平化操作只能对最外层进行操作 //println(array.flatten.flatten) val array = Array( "Hello Scala", "Hello Hadoop" ) //println(array.flatten.mkString(",")) println(array.flatMap( str => { str.split(" ") } ).mkString(","))
数据操作 filter
val array = ArrayBuffer(1,2,3,4) // filter方法可以对集合中的每一条数据进行筛选过滤 // 满足条件(true)的数据保留,不满足条件(false)的数据丢弃 val r = array.filter( num => { num % 2 != 0 } ) println(r) }
数据操作 groupby
// val array = ArrayBuffer(1,2,3,4) // // // 根据指定的规则对每一条数据进行分组 // val r = array.groupBy( // num => { //// if ( num % 2 == 0 ) { //// "偶数" //// } else { //// "奇数" //// } // num % 2 // } // ) // // println(r) val array = ArrayBuffer( "Hello", "Scala", "Hadoop", "Spark" ) println(array.groupBy(_.substring(0, 1)))
数据操作 groupby
//val array = ArrayBuffer(1,4,2,3) val array = ArrayBuffer("1", "11", "2", "3", "22") // 排序:通过指定的规则对每一条数据进行排序处理, 默认为升序 println(array.sortBy( num => num.toInt )) println(array.sortBy(num => num.toInt)(Ordering.Int.reverse))
数据操作 wordcount
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // TODO 1. 读取文件,获取原始数据
2 // line => Hello Scala
3 val source: BufferedSource = Source.fromFile("data/word.txt")
4 val lines: Array[String] = source.getLines().toArray
5 source.close()
6
7 // TODO 2. 将原始数据进行切分成一个一个的单词
8 // "Hello Scala" => "Hello", "Scala"
9 val words = lines.flatMap(
10 line => {
11 line.split(" ")
12 }
13 )
14
15 // TODO 3. 对分词的结果进行分组操作(相同的单词放置在一起)
16 // "Hello", "Hello" => { "Hello"=>List( Hello, Hello ) }
17 val wordGroup: Map[String, Array[String]] = words.groupBy(word => word)
18
19 // TODO 4. 对分组后的数据进行数量的统计
20 // 如果数据在转换时,无需对key进行操作,只对v进行处理时,可以使用mapValues方法
21 // { "Hello"=>List( Hello, Hello ) }
22 // =>
23 // { "Hello"=>2 }
24 val wordCount = wordGroup.mapValues(
25 v => {
26 v.size
27 }
28 )
29
30 // TODO 5. 将统计结果打印在控制台
31 println(wordCount)
// line => Hello Scala val source: BufferedSource = Source.fromFile("data/word.txt") val lines: Array[String] = source.getLines().toArray source.close() val wordCount = lines .flatMap(_.split(" ")) .groupBy(word => word) .mapValues(_.size) println(wordCount)
本文为原创文章,转载请标明出处