import org.junit.Test /** * Array、ArrayBuffer的构造,操作,遍历等 */ class C2_Array { @Test def arrTest(): Unit = { //在Scala中,Array代表的含义与Java中类似,也是长度不可改变的数组。 // 此外,由于Scala与Java都是运行在JVM中,双方可以互相调用,因此Scala数组的底层实际上是Java数组。 // 例如字符串数组在底层就是Java的String[],整数数组在底层就是Java的Int[]。 // 数组初始化后,长度就固定下来了,而且元素全部根据其类型初始化 val a = new Array[Int](10) println(a(0)) a(0) = 1 val a2 = new Array[String](10) // 可以直接使用Array()创建数组,元素类型自动推断 val a3 = Array("hello", "world") a3(0) = "hi" val a4 = Array("leo", 30) println(a4.toBuffer) } @Test def arrayBufferTest(): Unit = { //在Scala中,如果需要类似于Java中的ArrayList这种长度可变的集合类,则可以使用ArrayBuffer。 // 如果不想每次都使用全限定名,则可以预先导入ArrayBuffer类 import scala.collection.mutable.ArrayBuffer val arrayBuffer = ArrayBuffer[Int]() // 使用+=操作符,可以添加一个元素,或者多个元素 // 这个语法必须要谨记在心!因为spark源码里大量使用了这种集合操作语法! arrayBuffer += 1 println(arrayBuffer) arrayBuffer += (2, 3, 4, 5) println(arrayBuffer) // 使用++=操作符,可以添加其他集合中的所有元素 arrayBuffer ++= Array(6, 7, 8, 9, 10) println(arrayBuffer) //使用trimEnd()函数,可以取指定个数的元素 arrayBuffer.trimEnd(5) println(arrayBuffer) // 使用insert()函数可以在指定位置插入元素 // 但是这种操作效率很低,因为需要移动指定位置后的所有元素 //在5处插入6 arrayBuffer.insert(5, 6) println(arrayBuffer) //在6处插入7, 8, 9, 10 arrayBuffer.insert(6, 7, 8, 9, 10) println(arrayBuffer) // 使用remove()函数可以移除指定位置的元素 arrayBuffer.remove(1) println(arrayBuffer) arrayBuffer.remove(1, 3) println(arrayBuffer) // Array与ArrayBuffer可以互相进行转换 println(arrayBuffer.toArray.mkString(" ")) } @Test def forTest(): Unit = { import scala.collection.mutable.ArrayBuffer val b = ArrayBuffer[Int](1, 2, 3, 4, 5) // 使用for循环和until遍历Array / ArrayBuffer // until是RichInt提供的函数 // until不包括b.length,to包括 for (i <- 0 until b.length) println(b(i)) println() // 跳跃遍历Array / ArrayBuffer for (i <- 0 until(b.length, 2)) println(b(i)) println() // 从尾部遍历Array / ArrayBuffer for (i <- (0 until b.length).reverse) println(b(i)) println() // 使用“增强for循环”遍历Array / ArrayBuffer for (e <- b) println(e) } @Test def opTest(): Unit = { //数组常见操作 // 数组元素求和 val a = Array(1, 2, 4, 3, 5) println(a.sum) // 获取数组最大值 println(a.max) // 对数组进行排序 scala.util.Sorting.quickSort(a) // 获取数组中所有元素内容 println(a.mkString) println(a.mkString(" ")) println(a.mkString("<", ",", ">")) // toString函数 println(a.toString) } @Test def yieldTest(): Unit = { import scala.collection.mutable.ArrayBuffer //使用yield和函数式编程转换数组 // 对Array进行转换,获取的还是Array val a = Array(1, 2, 3, 4, 5) val squareArr = for (ele <- a) yield ele * ele println(squareArr.mkString(" ")) // 对ArrayBuffer进行转换,获取的还是ArrayBuffer val b = ArrayBuffer[Int]() b += (1, 2, 3, 4, 5) println(b) val squareArrBuf = for (ele <- b) yield ele * ele println(squareArrBuf) // 结合if守卫,仅转换需要的元素 val evenSquareArr = for (ele <- a if ele % 2 == 0) yield ele * ele println(evenSquareArr.mkString(" ")) // 使用函数式编程转换数组(通常使用第一种方式) val evenDoubleArr = a.filter(_ % 2 == 0).map(2 * _) println(evenDoubleArr.mkString(" ")) } @Test def cleanTest(): Unit = { import scala.collection.mutable.ArrayBuffer val a = ArrayBuffer[Int](1, 2, 3, 4, 5, -1, -3, -5, -9) // 移除第一个负数之后的所有负数,性能较差,多次移动数组 var foundFirstNegative = false var arrayLength = a.length var index = 0 while (index < arrayLength) { if (a(index) >= 0) { index += 1 } else { if (!foundFirstNegative) { foundFirstNegative = true; index += 1 } else { a.remove(index); arrayLength -= 1 } } } println(a) } @Test def cleanTest2(): Unit = { import scala.collection.mutable.ArrayBuffer //移除第一个负数之后的所有负数(改良版) // 重新构建数组 val a = ArrayBuffer[Int]() a += (1, 2, 3, 4, 5, -1, -3, -5, -9) // 每记录所有不需要移除的元素的索引,稍后一次性移除所有需要移除的元素 // 性能较高,数组内的元素迁移只要执行一次即可 var foundFirstNegative = false val keepIndexes = for (i <- 0 until a.length if !foundFirstNegative || a(i) >= 0) yield { if (a(i) < 0) foundFirstNegative = true i } for (i <- 0 until keepIndexes.length) { a(i) = a(keepIndexes(i)) } a.trimEnd(a.length - keepIndexes.length) println(a) } }