十、Scala的数组、元组、列表、集、映射、迭代器和函数式编程


1. 数组

数组是用来存储多个同类型元素的容器。每个元素都有编号/下标/脚标/索引,且编号都是从0开始数的。

1.1 定长数组

特点:

  • 数组长度不允许改变
  • 数组的内容是可变的

语法:
格式一:通过指定长度定义数组

val/var 变量名 = new Array[元素类型](数组长度)

格式二:通过指定元素定义数组

val/var 变量名 = new Array(元素1, 元素2, 元素3...)

注意:

  • 数组的泛型用[]来指定
  • 使用数组名(索引)来获取数组中的元素
  • 数组元素是有默认值的,Int:0, Double:0.0, String:null
  • 通过数组名.length数组名.size来获取数组的长度

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		var arr1 = new Array[Int](10)
		arr1(0) = 11
		println(arr1(0))

		//2
		var arr2 = Array("java", "scala", "python")
		println(arr2.length)
		println(arr2.size)
	}
}
//1
//3
//3

1.2 变长数组

特点:
数组的长度和内容都是可变的,可以往数组中添加、删除元素
语法:
创建变长数组,需要先导入ArrayBuffer类

import scala.collection.mutable.ArrayBuffer

定义格式一:创建空的ArrayBuffer变长数组

val/var 变量名 = ArrayBuffer[元素名称]()

定义格式二:创建带有初始元素的ArrayBuffer变长数组

val/var 变量名 = ArrayBuffer(元素1, 元素2, 元素3...)

示例一:定义变长数组
在这里插入图片描述

import scala.collection.mutable.ArrayBuffer

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		var arr1 = ArrayBuffer[Int]()

		//2
		var arr2 = ArrayBuffer("hadoop", "storm", "spark")

		//3
		println(arr1)
		println(arr2)
	}
}
//ArrayBuffer()
//ArrayBuffer(hadoop, storm, spark)

示例二:增删改元素
格式:
使用+=添加单个元素
使用-=删除单个元素
使用++=追加一个数组到变长数组中
使用--=移除变长数组中的指定多个元素

需求:
在这里插入图片描述

import scala.collection.mutable.ArrayBuffer

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		var arr1 = ArrayBuffer("hadoop", "spark", "flink")

		//2
		arr1 += "flume"

		//3
		arr11 -= "hadoop"

		//4
		arr1 ++= Array("hive", "sqoop")

		//5
		arr1 --= Array("sqoop", "spark")

		//6
		println(arr1)
	}
}
//ArrayBuffer(flink, flume, hive)

1.3 遍历数组

Scala中,可以使用以下两种方式遍历数组:

  • 使用索引遍历数组中的元素
  • 使用for表达式直接遍历数组中的元素

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		var arr = ArrayBuffer(1, 2, 3, 4, 5)

		//2
		//方式一:通过索引实现
		//i:数组中每个元素的索引  to:包左也包右
		for(i <- 0 to arr1.length - 1) println(arr1(i))
		println("-" * 15)

		//i:数组中每个元素的索引  until:包左不包右
		for(i <- 0 until arr1.length) println(arr1(i))
		println("-" * 15)

		//方式二:直接获取元素
		//i:数组中的每个元素
		for(i <- arr1) println(i)
	}
}
//1
//2
//3
//4
//5
//---------------
//1
//2
//3
//4
//5
//---------------
//1
//2
//3
//4
//5

1.4 数组常用算法

  • sum() 方法:求和
  • max() 方法:求最大值
  • min() 方法:求最小值
  • sorted() 方法:排序,返回一个新的数组
  • reverse() 方法:反转,返回一个新的数组

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		val arr = Array(4, 1, 6, 5, 2, 3)

		//2
		println(arr.sum)
		println(arr.max)
		println(arr.min)
		val arr2 = arr.sorted
		val arr3 = arr.reverse

		//3.打印结果
		for(i <- arr) println(i)  //4,1,6,5,2,3
		for(i <- arr2) println(i) //1,2,3,4,5,6
		for(i <- arr3) println(i) //3,2,5,6,1,4
	}
}
//21
//6
//1
//剩余结果已写在注释

2. 元组

元组一般用来存储多个不同类型的值。且元组的长度和元素都是不可变的。

2.1 格式

格式一:通过小括号实现

val/var 元组 = (元素1, 元素2, 元素3...)

格式二:通过箭头实现(只适合于元组中只有两个元素的情况)

val/var 元组 = 元素1->元素2

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.通过小括号形式实现
		val tup1 = ("lee", 23)
		//2.通过箭头方式实现
		val tup2 = "mike" -> 24
		//3.打印结果
		println(tup1)
		println(tup2)
	}
}
//(lee,23)
//(mike,24)

2.2 访问元组中的元素

Scala中,可以通过元组名._编号的形式来访问元组中的元素,_1表示访问第一个元素,以此类推;也可以通过元组名.productIterator的方式,来获取该元组的迭代器,从而实现遍历元组

格式一:访问元组中的单个元组

println(元组名._1)  //打印元组的第一个元素
println(元组名._2)  //打印元组的第二个元素
...

格式二:遍历元组

val tuple1 = (1, 值2, 值3...) //可以有多个值
val it = tuple1.productIterator //获取当前元组的迭代器对象
for(i <- it) println(i)

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.
		val tup1 = "lee" -> "male"
		//2.
		//方式一:通过_编号获取,编号是从1开始技术的
		println(tup1._1)
		println(tup1._2)

		//方式二:通过迭代器遍历
		val it = tup1.prodcutIterator
		for(i < it) println(i)
	}
}
//lee
//male
//lee
//male

3. 列表

列表是Scala最重要也是最常用的一种数据结构,它存储的数据的特点是:有序,可重复

  • 有序 - 元素存入顺序和取出顺序是一致的
  • 可重复 - 列表中可以添加重复元素

Scala中列表分为不可变列表和可变列表。

3.1 不可变列表

不可表列表的元素、长度都是不可变的。

语法:
格式一:通过小括号直接初始化

val/var 变量名 = List(元素1, 元素2, 元素3...)

格式二:通过Nil创建一个空列表

val/var 变量名 = Nil

格式三:使用::方法实现 (必须在最后添加一个Nil)

val/var 变量名 = 元素1 :: 元素2 :: Nil

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.
		val list1 = List(1, 2, 3, 4)
		//2.
		val list2 = Nil
		//3.
		val list3 = -2::-1::Nil
		//4.打印结果
		println(list1)
		println(list2)
		println(list3)
	}
}
//List(1, 2, 3, 4)
//List()
//List(-2, -1)

3.2 可变列表

可变列表的元素、长度都是可变的。

语法:
要使用可变列表,必须先导包
(技巧:可变集合都在mutable包中,不可变集合都在immutable包中(默认))

import scala.collection.mutable.ListBuffer

格式一:创建空的可变列表

val/var 变量名 = ListBuffer[数据类型]()

格式二:通过小括号直接初始化

val/var 变量名 = ListBuffer(元素1, 元素2, 元素3...)

示例:
在这里插入图片描述

import scala.collection.mutable.ListBuffer

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.
		val list1 = ListBuffer[Int]()
		//2.
		val list2 = ListBuffer(1, 2, 3, 4)
		//3.打印结果
		println(list1)
		println(list2)
	}
}
//ListBuffer()
//ListBuffer(1, 2, 3, 4)

可变列表的常见操作:
在这里插入图片描述
示例:
在这里插入图片描述

import scala.collection.mutable.ListBuffer

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.
		val list1 = ListBuffer(1, 2, 3)
		//2.
		println(list1(0))
		//3.
		list1 += 4
		//4.
		list1 ++= List(5, 6, 7)
		//5. 
		list1 -= 7
		//6. 
		list1 --= List(3, 4)
		//7.
		val list2 = list1.toList
		//8.
		val arr = list1.toArray
		//9.打印结果
		println(list1) //ListBuffer(1, 2, 5, 6)
		println(list2) //List(1, 2, 5, 6)
		println(arr) //[I@4411d970  //输出语句直接打印数组,打印的是数组的地址值
	}
}

3.3 列表的常用操作

在这里插入图片描述
示例一:基础操作
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.
		val list1 = List(1, 2, 3, 4)
		//2.
		println(list1.isEmpty)  //false
		//3.
		val list2 = List(4, 5, 6)
		//4.
		val list3 = list1 ++ list2
		println(list3) //List(1, 2, 3, 4, 4, 5, 6)
		//5. 
		println(list1.head) //1
		//6. 
		println(list.tail) //List(2, 3, 4)
		//7.
		println(list1.reverse) //List(4, 3, 2, 1)
		//8.这里的3表示:前3个元素都是前缀元素
		println(list1.take(3)) //List(1, 2, 3)
		//9.这里的3表示:除了前3个是前缀元素外,剩下都是后缀元素
		println(list1.drop(3)) //List(4)
	}
}

示例二:扁平化(压平)
扁平化表示嵌套列表中的所有具体元素单独的放到一个新列表中(如果某个列表中的所有元素都是列表,那么这样的列表称为嵌套列表
在这里插入图片描述
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.
		val list1 = List(List(1, 2), List(3), List(4, 5))
		//2.
		val list2 = list1.flatten
		//3.
		println(list1) //List(List(1, 2), List(3), List(4, 5))
		println(list2) //List(1, 2, 3, 4, 5)
	}
}	

示例三:拉链与拉开
拉链:将两个列表,组合成一个元素为元组的列表
拉开:将一个包含元组的列表,拆解成包含两个列表的元组

在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.
		val names = List("张三", "李四", "王五")
		//2.
		val ages = List(23, 24, 25)
		//3.
		val list1 = names.zip(ages) //List(("张三", 23),("李四", 24),("王五", 25))
		//4.
		val tuple1 = list1.unzip //(List("张三", "李四", "王五"), List(23, 24, 25))
	}
}	

示例四:列表转字符串
将列表转换成其对应的字符串形式,可以通过toString方法或者mkString方法实习,其中

  • toString方法:可以返回List中的所有元素
  • mkString方法:可以将元素以指定分隔符拼接起来(默认没有分隔符)

在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.
		val list1 = List(1, 2, 3, 4)
		//2.
		println(list1.toString) //List(1, 2, 3, 4)
		//简写形式,如果输出语句打印的是对象,默认会调用对象的toString()方法
		println(list1) //List(1, 2, 3, 4)
		//3.
		println(list1.mkString) //1234
		println(list1.mkString(":")) //1:2:3:4
	}
}

示例五:并集、交集、差集

  • l1.union(l2)表示获取l1和l2所有的元素(不去重)
    • 如果想要去除重复元素,则可以通过distinct实现
  • l1.intersect(l2)表示获取l1,l2都有的元素
  • l1.diff(l2)表示获取l1中有,但l2中没有的元素

在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		val list1 = List(1, 2, 3, 4)
		//2
		val list2 = List(3, 4, 5, 6)
		//3
		val unionList = list1.union(list2) //List(1, 2, 3, 4, 3, 4, 5, 6)
		//4
		val distinctList = unionList.distinct //List(1, 2, 3, 4, 5, 6)
		//5
		val intersectList = list1.intersect(list2) //List(3, 4)
		//6
		val diffList = list1.diff(list2) //List(1, 2)
	}
}

4. 集

集代表没有重复的集合,特点是:唯一,无序
Scala中的集分为不可变集(和可变集

4.1 不可变集

不可变集的元素、长度都不可变

语法:
格式一:创建一个空的不可变集

val/var 变量名 = Set[类型]()

格式二:给定元素来创建一个不可变集

val/var 变量名 = Set(元素1, 元素2, 元素3...)

示例一:创建不可变集:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		val set1 = Set[]()
		//2
		val set2 = Set(1, 1, 3, 2, 4, 8)
		//3
		println(set1) //Set()
		println(set2) //Set(1, 2, 3, 8, 4)
	}
}

示例二:不可变集的常见操作
在这里插入图片描述

在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		val set1 = Set(1, 1, 3, 2, 4, 5)
		//2
		println(set1.size)  //5
		//3
		for(i <- set1) println(i) // 5 1 2 3 4
		//4
		val set2 = set1 - 1
		println(set2) //Set(5, 2, 3, 4)
		//5
		val set3 = set1 ++ Set(6,7,8)
		println(set3) //Set(5, 1, 6, 2, 7, 3, 8, 4)
		//6
		val set4 = set1 ++ List(6,7,8,9)
		println(set4) //Set(5, 1, 6, 9, 2, 7, 3, 8, 4)
	}
}

4.2可变集

可变集的元素、长度都可变,它的创建方式和不可变集的创建方式一致,只不过需要先导入可变集类
手动导入:import scala.collection.mutable.Set

示例:
在这里插入图片描述

import scala.collection.mutable.Set

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		val set1 = Set(1, 2, 3, 4)
		//2
		set1 += 5  //Set(1, 5, 2, 3, 4)
		//3
		//方式一:set1 ++= Set(6, 7, 8) 
		//方式二:
		set1 ++= List(6, 7, 8)  //Set(1, 5, 2, 6, 3, 7, 4, 8)
		//4
		set1 -= 1 //Set(5, 2, 6, 3, 7, 4, 8)
		//5
		//方式一:set1 --= Set(3, 5, 7) 
		//方式二:
		set1 --= List(3, 5, 7)   //Set(2, 6, 4, 8)
	}
}

5. 映射

映射(Map)是由键值对(key, value)组成的集合,特点是键具有唯一性,但是值可以重复
Scala中可以分为不可变Map和可变Map

5.1 不可变Map

不可变Map的元素、长度都不可变

语法:
方式一:通过箭头的方式实现

val/var map = Map(->,->,->...) //推荐,可读性更好

方式二:通过小括号的方式实现

val/var map = Map((,), (,), (,)...)

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		//方式一
		val map1 = Map("张三" -> 23, "李四" -> 24, "李四" -> 40)
		//方式二
		val map2 = Map(("张三", 23), ("李四", 24), ("李四", 40))
		//2
		println(map1) //Map(张三 -> 23, 李四 -> 40)
		println(map2) //Map(张三 -> 23, 李四 -> 40)
	}
}

5.2 可变Map

可变Map的元素、长度都可变,定义语法与不可变Map一致,只不过需要先手动导包: import scala.collection.mutable.Map

示例:
在这里插入图片描述

import scala.collection.mutable.Map`

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		//方式一
		val map1 = Map("张三" -> 23, "李四" -> 24)
		//方式二
		val map2 = Map(("张三", 23), ("李四", 24))
		//2
		map1("张三") = 30
		//3
		println(map1) //Map(张三 -> 30, 李四 -> 24
		println(map2) //Map(张三 -> 23, 李四 -> 24)
	}
}

5.3 Map基本操作

格式:
在这里插入图片描述
示例:
在这里插入图片描述

import scala.collection.mutable.Map`

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		val map1 = Map("张三" -> 23, "李四" -> 24)
		//2
		println(map1("张三")) //23
		//3
		println(map1.keys) //Set(张三,李四)
		//4
		println(map1.values) //MapLike(23, 24)
		//5
		for((k, v) <- map1) println(k, v) 
		//6
		println(map1.getOrElse("王五", -1))  //-1
		//7
		//val map2 = map1 + "王五" -> 25
		//println(map2) //(Map(张三 -> 23, 李四 -> 24)王五,25))
		map1 += "王五" -> 25
		println(map1) //Map(王五 -> 25, 张三 -> 23, 李四 -> 24)
		//8
		map -= "李四" //根据键删除相应的键值对 //Map(王五 -> 25, 张三 -> 23)
	}
}

6. 迭代器

Scala针对每一类集合都提供了一个迭代器(iterator),用来迭代访问集合

注意:

  • 使用 iterator 从集合获取迭代器
    • 迭代器的两个方法:
      • hasNext方法: 查询容器是否有下一个元素
      • next 方法:返回迭代器的下一个元素,没有则会抛出NoSuchElementException
  • 每一个迭代器都是有状态的(即迭代完后保留在最后一个元素的位置,再次使用则抛出NoSuchElementException
  • 可以使用while或for来逐个获取元素

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1
		val list1 = List(1, 2, 3, 4, 5)
		//2
		//2.1通过集合对象获取其对应的迭代器对象
		val it = list1.iterator
		//2.2判断迭代器中是否有下一个元素
		while (it.hasNext) {
			//2.3如果有,则获取元素,并打印
			println(it.next())
		}
		//当迭代器使用完毕后,再次通过next()方法获取元素
		println(it.next()) //抛出异常NoSuchElementException
	}
}
//1
//2
//3
//4
//5

7. 函数式编程

函数式编程指定就是方法的参数列表可以接收函数对象
例如:add(10,20)不是函数式编程,而add(函数对象)这种格式就是函数式编程
将来编写Spark/Flink的大量业务代码时,都会使用到函数式编程

在这里插入图片描述

7.1 遍历(foreach)

格式:

def foreach(f:(A) => Unit) : Unit

//简写形式
def foreach(函数)

说明:
在这里插入图片描述
在这里插入图片描述
示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个列表
		val list1 = List(1, 2, 3, 4)
		//2.使用foreach方法遍历打印每个元素
		//函数的格式: (函数的参数列表) => {函数体}
		//x表示: 列表list1中的每一个元素
		list1.foreach((x:Int) => {println(x)})

		//简写版本:
		list1.foreach(x => println(x))
	}
}
//1
//2
//3
//4

7.2 简化函数定义

方式一:通过类型判断来简化函数定义

  • 因为使用foreach来迭代列表,而列表中的每个元素类型是确定的,所以我们可以通过类型推断让Scala自动推断除集合中每个元素参数的类型,集:我们创建函数时,可以省略其参数列表的类型

方式二:通过下划线来简化函数定义

  • 当函数参数只在函数体中出现一次,而且函数体没有嵌套调用时,可以使用下划线来简化函数定义

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个列表
		val list1 = List(1, 2, 3, 4)
		//2.使用foreach方法遍历打印每个元素
		//普通写法:
		list1.foreach((x:Int) => {println(x)})

		//使用类型推断来简化函数定义:
		list1.foreach(x => println(x))

		//使用下划线来简化函数定义
		list1.foreach(println(_))
		
	}
}
//1
//2
//3
//4

7.3 映射(map)

集合的映射操作是指将一种数据类型转换成另一种数据类型的过程,它是在进行数据计算是,甚至将来写Spark/Flink程序时用得最多的操作
例如:把List[Int]转换成List[String]

格式:

def map[B](f: (A) => B): TraversableOnce[B]

//简写形式
def map(函数对象)

说明:
在这里插入图片描述
在这里插入图片描述

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个列表
		val list1 = List(1, 2, 3, 4)
		//2.将上述的数字转换成相应个数的'*'
		//普通写法:
		val list2 = list1.map((x:Int) => {"*" * x})

		//使用类型推断来简化函数定义:
		val list2 = list1.map(a => "*" * a)

		//使用下划线来简化函数定义
		val list2 = list1.map("*" * _)
		
		println(list2)
	}
}
//List(*, **, ***, ****)

7.4 扁平化映射(flatMap)

扁平化映射可以理解为先map(将列表中的元素转换为一个List),后flatten。
在这里插入图片描述
格式:

def flatMap[B](f:(A)) => GenTraversableOnce[B]):TraversableOnce[B]

//简写形式
def flatMap(f:(A) => 要将元素A转换成的集合B的列表)

说明:
在这里插入图片描述
示例:
在这里插入图片描述
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个包含了若干个文本行的列表
		val list1 = List("hadoop hive spark flink flume", "kudu hbase sqoop storm")
		
		//2.获取到文本行中的每一个单词,并将每一个单词都放到列表中
		//方式一:先mao,然后flatten
		val list2 = list1.map((x:String) => {x.split(" ")}) 
		println(list2) //List(Array(),Array())
		val list3 = list2.flatten
		println(list3) //List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)

		//方式二:直接通过flatMap方法实现
		//val list4 = list1.flatMap((x:String) => {x.split(" ")}) 
		//简化:
		val list4 = list1.flatMap(_.split(" ")) 
		println(list4) //List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)
	}
}

7.5 过滤(filter)

过滤指的是过滤出(筛选出)符合一定条件的元素

格式:

def filter(f:(A) => Boolean):TraversableOnce[A]

//简写形式:
def filter(f:(A) => 筛选条件)

说明:
在这里插入图片描述
在这里插入图片描述
示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个数字列表
		//val list1 = List(1,2,3,4,5,6,7,8,9)
		val list1 = (1 to 9).toList
		
		//2.过滤除所有的偶数
		//val list2 = list1.filter(x => x % 2 == 0) 
		//简洁:
		val list2 = list1.filter(_ % 2 == 0) 
		println(list2) //List(2, 4, 6, 8)
	}
}

7.6 排序

Scala集合中,可以使用以下三种方式进行排序:
在这里插入图片描述

7.6.1 默认排序(sorted)

默认排序指的是对列表元素按照升序进行排列。如果需要降序排列,则升序后再通过reverse实现

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个数字列表
		val list1 = List(31297)
		
		//2.对列表进行升序排列
		val list2 = list1.sorted 
		println(list2) //List(1, 2, 3, 7, 9)

		//3.对列表进行降序排列
		val list3 = list2.reverse
		println(list3) //List(9, 7, 3, 2, 1)
	}
}

7.6.2 指定字段排序(sortBy)

指定字段排序指的是对列表元素根据传入的函数转换后,再进行排序(例如:根据列表List(“01 hadoop”, “02 flume”)的字母进行排序)

格式:

def sortBy[B](f:(A) => B):List[A]

//简写形式
def sortBy(函数对象)

说明:
在这里插入图片描述

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个列表
		val list1 = List("01 hadoop", "02 flume", "03 hive", "04 spark")
		
		//2.按照单词字母进行排序
		//x表示:list1列表中的每个元素  "01 hadoop", "02 flume"
		//x.split(" ")表示:  Array("01", "hadoop"), Array("02", "flume")
		//x.split(" ")(1)表示:"hadoop", "flume"
		val list2 = list1.sortBy(x => x.split(" ")(1)) 
		println(list2) //List(02 flume, 01 hadoop, 03 hive, 04 spark)
	}
}

7.6.3 自定义排序(sortWith)

自定义排序指的是根据一个自定义的函数(规则)来进行排序

格式:

def sortWith(f:(A, A) => Boolean):List[A]

//简写形式
def sortWith(函数对象:表示自定义的比较规则)

说明:
在这里插入图片描述

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个列表
		val list1 = List(2, 3, 1, 6, 4, 5)
		
		//2.使用sortWith对列表进行降序排列
		//x表示:前边的元素
		//y表示:后边的元素
		//val list2 = list1.sortWith((x, y) => x > y) 
		
		//简练:
		//第一个下划线_相当于上边的x
		//第二个下划线_相当于上边的y
		val list2 = list1.sortWith(_ > _)
		println(list2) //List(6, 5, 4, 3, 2, 1)
	}
}

7.7 分组(groupBy)

分组指的是将数据按照指定条件进行分组,从而方便我们对数据进行统计分析

格式:

def groupBy[K](f:(A) => K):List[A]

//简写形式
def gourpBy(f:(A) => 具体的分组代码)

说明:
在这里插入图片描述
在这里插入图片描述

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个列表
		val list1 = List("刘德华" -> "男""刘亦菲" -> "女""胡歌" -> "男")
		
		//2.按照性别进行分组
		//x表示列表list1中的每个元素 "刘德华" -> "男"
		//x._2表示获取的是性别 "男"
		//val map1 = list1.groupBy(x => x._2) 
		//简练:
		val map1 = list1.groupBy(_ => _._2) 
		println(map1)//Map(男 -> List(刘德华 -> 男, 胡歌 -> 男), 女 -> List(刘亦菲 -> 女))
		
		//3.统计不同性别的学生人数
		//x表示map1中的每个元素  男 -> List(刘德华 -> 男, 胡歌 -> 男)
		//x._1表示性别    "男"
		//x._2表示符合条件的所有数据    "男" 对应 List(刘德华 -> 男, 胡歌 -> 男)
		val map2 = map1.map(x => x._1 -> x._2.size)
		println(map2) //List(男 -> 2, 女 -> 1)
	}
}

7.8 聚合操作

聚合操作指的是将一个列表中的数据合并为一个,常用来统计分析中

7.8.1 聚合(reduce)

reduce表示将列表传入一个函数进行聚合计算

格式:

def reduce[A1 >: A](op:(A1, A1) => A1):A1

//简写形式
def reduce(op:(A1, A1) => A1)

说明:
在这里插入图片描述
在这里插入图片描述
注意:

  • reduce和reduceLeft效果一致,表示从左到右计算
  • reduceRight表示从右到左计算

示例:

在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个列表
		val list1 = (1 to 10).toList
		
		//2.使用reduce计算所有元素的和
		//x表示聚合后的操作结果
		//y表示后一个元素
		//val list2 = list1.reduce((x, y) => x + y) 
		//简练:第一个下划线相当于上边的x,第二个下划线相当于上边的y
		val list2 = list1.reduce(_ + _) 
		println(list2)//55
		val list3 = list1.reduceLeft(_ + _) 
		println(list3)//55
		val list4 = list1.reduceRight(_ + _) 
		println(list4)//55
		
		//如果是相减操作,则reduceLeft和reduceRight得到的结果不一样
		println(list1.reduce(_ - _)) //-53
		println(list1.reduceRight(_ - _)) //-5
	}
}

7.8.2 折叠(fold)

fold与reduce很像,只不过多了一个指定初始值参数
格式:

def fold[A1 >: A](z: A1)(op:(A1, A1) => A1):A1

//简写形式
def (初始值)(op:(A1, A1) => A1)

说明:
在这里插入图片描述

注意:

  • fold和foldLeft效果一致,表示从左到右计算
  • foldRight表示从右到左计算

示例:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.有一个列表
		val list1 = (1 to 10).toList
		
		//2.使用fold计算所有元素的和
		//100表示初始化值
		//(x,y) => x + y 表示函数对象
		val list2 = list1.fold(100)((x, y) => x + y) 
		//简练:第一个下划线相当于上边的x,第二个下划线相当于上边的y
		val list2 = list1.fold(100)(_ + _) 
		println(list2)//155
		val list3 = list1.foldLeft(100)(_ + _) 
		println(list3)//155
		val list4 = list1.foldRight(100)(_ + _) 
		println(list4)//155
	}
}

8. 案例:学生成绩单

需求:
在这里插入图片描述

object ClassDemo {
	def main(args: Array[String]):Unit = {
		//1.定义列表,记录学生成绩
		val stuList = List(("张三",37,90,100),("李四",90,73,81),("王五",60,90,76),("赵六",59,21,72),("田七",100,100,100),)
		
		//2.获取所有语文成绩在60分以上的同学信息
		//val chineseList = stuList.filter(x => x._2 >= 60)
		//简化:
		val chineseList = stuList.filter(_ => _._2 >= 60)
		
		//3.获取所有学生的总成绩
		val countList = stuList.map(x => x._1 -> (x._2 + x._3 + x._4)) //这里不能用下划线简化,因为x出现了四次了

		//4.按照总成绩降序排列
		//val sortList = countList.sortWith((x, y) => x._2 > y._2) 
		//简化:
		val sortList = countList.sortWith(_._2 > _._2) 
	}
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值