Scala进阶之路-高级数据类型之数组的使用
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.数组的初始化方式
1>.长度不可变数组Array
注意:顾名思义,长度不可变数组指的是数组的长度不可变,但是数组的内容是可以变换的!
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 object MyArray { 9 10 def main(args: Array[String]): Unit = { 11 /** 12 * 定义一个固定长度的数组,长度可变,内容可变(因为变量我们是用var关键字修饰)。 13 * [String] :表示的是数组的泛型,即该数组只能接收String类型的数据哟 14 * (3) : 这个数字3表示的是arr数组的长度 15 */ 16 var arr :Array[String] = new Array[String](3) 17 /** 18 * 当然,上面的那种方式是写了arr变量的数据类型为一个数组,我们不懈也是可以的,因为Scala解释器会默认帮我们隐式转换的哟 19 */ 20 var arr2 = new Array[String](3) 21 22 /** 23 * 定义定长数组, 长度不可变, 内容可变(因为变量是由val关键字修饰) 24 */ 25 val arr3 = Array (1,2,3) //我们可以直接初始化数组的内容,这个时候就不需要new关键字啦! 26 27 /** 28 * 接下来我们分别修改我们定义的3个数组中的内容,具体操作如下 29 */ 30 arr(0) = "yinzhengjie" 31 arr2(1) = "尹正杰" 32 arr3(2) = 100 33 34 //我们直接调用数组的toBuffer方法,因为该方法重写了toString方法。 35 println(arr.toBuffer.toString()) 36 println(arr2.toBuffer.toString()) 37 println(arr3.toBuffer.toString()) 38 } 39 } 40 41 42 43 /* 44 以上代码执行结果如下 : 45 ArrayBuffer(yinzhengjie, null, null) 46 ArrayBuffer(null, 尹正杰, null) 47 ArrayBuffer(1, 2, 100) 48 */
2>.长度可变数组(ArrayBuffer)
顾名思义,长度可变数组指的是数组的长度是可以变化的,其内容也是可以变化的哟!
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 /** 9 * 有可变(mutable包下存放)和不可变(immutable包下存放)两种类型,immutable 类型的集合初始化后就不能改变了,默认情况下使用的是 10 * 不可变数组,如果我们想要使用它可变类型数组类型ArrayBuffer,那么就需要导入这个包啦! 11 */ 12 import scala.collection.mutable.ArrayBuffer 13 14 15 object ArrayBuffDemo { 16 17 def main(args: Array[String]): Unit = { 18 //定义一个可变的数组 19 val arr = ArrayBuffer[String]("yinzhengjie","尹正杰","Scala") 20 //我们遍历定义的数组 21 arr.foreach(i => print(i + " ")) 22 println(" ==========我是分割线===========") 23 //我们往可变的数组内容中添加数据 24 arr+=("Shell","Python","Java","Golang") 25 //我们再次遍历定义的数组 26 arr.foreach(i => print(i + " ")) 27 } 28 } 29 30 /* 31 以上代码执行结果如下: 32 yinzhengjie 尹正杰 Scala 33 ==========我是分割线=========== 34 yinzhengjie 尹正杰 Scala Shell Python Java Golang 35 */
二.数组的常用方法
1>.映射方法(map)
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 object MyArray { 9 10 def main(args: Array[String]): Unit = { 11 /** 12 * 注意,如果直接给数组初始化的话,可以不用写new,直接使用数组的apply方法进行赋值操作,当然你可以省略".apply"这个方法。 13 */ 14 val arr = Array.apply[String]("yinzhengjie","尹正杰","Scala","Python","Golang") 15 16 /** 17 * 定义映射关系f1,功能是将传入的String类型的参数加上后缀;而arr数组经过map映射操作之后会返回一个新的数组。 18 */ 19 var f1 = (x:String) => x + "_2018" 20 val arr2 = arr.map(f1) 21 22 /** 23 * 当然,上面的这种写法也可以简写,如下: 24 */ 25 val arr3 = arr.map((x:String) => x + "_2018") //我们可以把上面的f1映射名称去掉,直接传入一个匿名函数 26 val arr4 = arr.map(x => x + "_2018") //这里的x的变量Scala会自动识别其数据类型 27 var arr5 = arr.map(_ + "_2018") //注意这个下划线("_")其实是表示的是arr数组中的每一个元素哟 28 29 println(arr.toBuffer.toString()) 30 println(arr2.toBuffer.toString()) 31 println(arr3.toBuffer.toString()) 32 println(arr4.toBuffer.toString()) 33 println(arr5.toBuffer.toString()) 34 } 35 } 36 37 38 39 /* 40 以上代码执行结果如下 : 41 ArrayBuffer(yinzhengjie, 尹正杰, Scala, Python, Golang) 42 ArrayBuffer(yinzhengjie_2018, 尹正杰_2018, Scala_2018, Python_2018, Golang_2018) 43 ArrayBuffer(yinzhengjie_2018, 尹正杰_2018, Scala_2018, Python_2018, Golang_2018) 44 ArrayBuffer(yinzhengjie_2018, 尹正杰_2018, Scala_2018, Python_2018, Golang_2018) 45 ArrayBuffer(yinzhengjie_2018, 尹正杰_2018, Scala_2018, Python_2018, Golang_2018) 46 */
2>.扁平化操作(flatten与flatMap)
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 object MyArray { 9 10 def main(args: Array[String]): Unit = { 11 /** 12 * 定义一个数组,里面存放两个字符串 13 */ 14 val arr = Array.apply[String]("yinzhengjie,尹正杰","Python,Shell,Golang,Java,Scala") 15 /** 16 * 我们使用映射方法map将里面的每个元素用逗号(",")进行切割,最终会将arr里面的两个字符串变成了2个数组, 17 * 而这两个数组中存放的是每个字符串按照“,”切割后的数组。 18 */ 19 val arr2 = arr.map(_.split(",")) 20 21 /** 22 * 接下来我们调用扁平化操作,使用flatten方法将两个arr2里面的两个数组去掉,直接把arr2里面嵌套的数组的每一个元素取出来。 23 */ 24 val arr3 = arr2.flatten 25 26 27 /** 28 * 如果你觉得由arr转换到arr3步骤过于繁琐,你可以这样写,“arr3 = arr.map(_.split(",")).flatten”,当然你也可以使用flatMap方法哟! 29 */ 30 val arr4 = arr.flatMap(_.split(",")) 31 32 /** 33 * 我们可以查看arr,arr2以及arr3的数组的内容以及长度。 34 */ 35 println(arr.toBuffer.toString(),arr.length) 36 println(arr2(0).toBuffer.toString(),arr2(1).toBuffer.toString(),arr2.length) 37 println(arr3.toBuffer.toString(),arr3.length) 38 println(arr4.toBuffer.toString(),arr4.length) 39 } 40 } 41 42 43 /* 44 以上代码执行结果如下 : 45 (ArrayBuffer(yinzhengjie,尹正杰, Python,Shell,Golang,Java,Scala),2) 46 (ArrayBuffer(yinzhengjie, 尹正杰),ArrayBuffer(Python, Shell, Golang, Java, Scala),2) 47 (ArrayBuffer(yinzhengjie, 尹正杰, Python, Shell, Golang, Java, Scala),7) 48 (ArrayBuffer(yinzhengjie, 尹正杰, Python, Shell, Golang, Java, Scala),7) 49 */
3>.遍历方法(foreach)
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 object MyArray { 9 10 def main(args: Array[String]): Unit = { 11 /** 12 * 定义一个数组,里面存放两个字符串 13 */ 14 val arr = Array.apply[String]("yinzhengjie,尹正杰","Python,Shell,Golang,Java,Scala") 15 16 /** 17 * 使用flatMap将arr数组中的数据扁平化 18 */ 19 val arr2 = arr.flatMap(_.split(",")) 20 21 /** 22 * 这个时候我们就可以用foreach方法遍历arr2数组中里面的每一个元素,foreach方法需要传递一个返回空值的方法。首先我们会想到打印的方法 23 */ 24 arr2.foreach(x => print(x + " ")) 25 arr2.foreach(println) 26 27 28 } 29 } 30 31 32 33 34 /* 35 以上代码执行结果如下 : 36 yinzhengjie 尹正杰 Python Shell Golang Java Scala yinzhengjie 37 尹正杰 38 Python 39 Shell 40 Golang 41 Java 42 Scala 43 */
4>.单词统计案例(wold count)
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 object MyArray { 9 10 def main(args: Array[String]): Unit = { 11 /** 12 * 定义一个数组,里面存放两个字符串 13 */ 14 val arr = Array.apply[String]("yinzhengjie,尹正杰,yinzhengjie","Python,Shell,Golang,Java,Scala,yinzhengjie") 15 16 17 /** 18 * flatMap: 19 * 进行扁平化操作,通过flatMap(_.split(","))可以将2个字符串按照空格切割成单词 20 * groupBy: 21 * 自然是排序操作了,即按照每个传进来的参数进行分组,即将相同的单词包装成一个数组 22 * mapValues: 23 * 传递的参数是一个数组,我们将传入的数组的长度取出 24 */ 25 val arr2 = arr.flatMap(_.split(",")).groupBy(x => x).mapValues(x => x.length) 26 arr2.foreach(x => print(x + " ")) 27 println(" =======我是分割线=======") 28 /** 29 * 排序功能: 30 * 又有map默认是无序的,因此我们可以将其转换成数组,然后在进行排序操作 31 * toList: 32 * 将arr3这个map类型转换成一个list类型 33 * sortBy: 34 * 排序操作,注意,x._1,其中x表示的是arr3转换成的list对象,而“_1”表示的是每一个元素的第一个参数,因此排序是按照字母来排序的哟,如果你想按照长度来排序的话把1改成2就好 35 */ 36 val arr3 = arr2.toList.sortBy(x=>x._1) 37 arr3.foreach(x => print(x + " ")) 38 } 39 } 40 41 42 43 44 /* 45 以上代码执行结果如下 : 46 (Shell,1) (Scala,1) (yinzhengjie,3) (Python,1) (尹正杰,1) (Golang,1) (Java,1) 47 =======我是分割线======= 48 (Golang,1) (Java,1) (Python,1) (Scala,1) (Shell,1) (yinzhengjie,3) (尹正杰,1) 49 */
如果想要按照数字进行倒序排列的话,我们可以看下面的一段代码也是world count单词统计:
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 object WordCount { 9 def main(args: Array[String]): Unit = { 10 val words: Array[String] = Array("hello yinzhengjie hello yinzhengjie Python", "hello Python hello yinzhengjie Scala Golang") 11 // words 数组中的每个元素按照空格(" ")进行切分。 12 val wordSplit: Array[Array[String]] = words.map((x: String) => x.split(" ")) 13 // 将数组中的Array扁平化 14 val fltWords: Array[String] = wordSplit.flatten 15 // 分组操作 : hello -> Array(hello, hello, hello, hello) 16 val mapWords: Map[String, Array[String]] = fltWords.groupBy((wd: String) => wd) 17 //生成map对象,得到类型这样的数据 : (hello, 4), (yinzhengjie,1)..... 18 val wrdResult: Map[String, Int] = mapWords.map(wdKV => (wdKV._1, wdKV._2.length)) 19 // Map不支持排序,需要将map转换成List, 调用sortBy方法按照单词数量降序排序(默认是升序,我们在前面加一个负号就可以实现倒序排列) 20 val sortResult: List[(String, Int)] = wrdResult.toList.sortBy(t => - t._2) 21 //遍历每一个元素 22 sortResult.foreach(i => println(i)) 23 } 24 } 25 26 27 28 /* 29 以上代码实现结果如下 : 30 (hello,4) 31 (yinzhengjie,3) 32 (Python,2) 33 (Scala,1) 34 (Golang,1) 35 */