元组(Tuple)
- 元组(Tuple)本身是一个用于存储1到多个元素的容器,需要注意的是,元组不是集合!!!Scala中所有的集合都在
scala.collection
包,Tuple是scala
包下,但是集合操作中很多时候需要使用到元组 - 如果元素类型一致且元素有序可重复,可以使用序列(
Seq
);如果元素类型一致且元素无序不可重复,可以使用集合(Set
);如果元素是键值对形式,可以使用映射(Map
);如果元素类型不一致,那么使用元组Tuple
- 需要注意的是,Scala中提供了Tuple1~Tuple22,即元组中最多能够存储22个元素
- 之前学习的Map中存储的就是Tuple2,即
Map(tuple2, tuple2, ...)
。Tuple2又称之为对偶元组 - 元组定义格式
package com.wph.tuple
object TupleDemo {
def main(args: Array[String]): Unit = {
// 定义格式
// 方式一
// 声明了Tuple3,元组定义好之后不可变
// 推荐使用这种方式
val t1: (String, Int, Char) = ("Bob", 15, 'm')
println(t1)
// 方式二
// val t2: Tuple4[String, Int, Double, Double] = Tuple4[String, Int, Double, Double]("Amy", 18, 165, 58)
// val t2: Tuple4[String, Int, Double, Double] = Tuple4("Amy", 18, 165, 58)
val t2: Tuple4[String, Int, Double, Double] = ("Amy", 18, 165, 58)
println(t2)
// 方式三
// 元组支持拆分
// val t3 = ("Sam", 15, "male")
// 如果要获取元组中的元素,通过 _顺序 的形式来获取
// val mame = t3._1
// val age = t3._2
// val gender = t3._3
// val (name, age, gender) = t3
// 简化
val (name, age, gender) = ("Sam", 15, "male")
println(name)
println(age)
println(gender)
val (r1, r2, r3) = randTo100()
println(r1)
println(r2)
println(r3)
}
def randTo100(): (Int, Int, Int) = {
val r1 = (Math.random() * 100).toInt
val r2 = (Math.random() * 100).toInt
val r3 = (Math.random() * 100).toInt
(r1, r2, r3)
}
}
6.遍历元组
package com.wph.tuple
object TupleDemo2 {
def main(args: Array[String]): Unit = {
// 遍历元组
val t = ("Bob", 10, "male", 4, 6, 152.2, 50.3, "北京")
// 产生迭代器 - 将元组中的所有的元素放入Iterator中返回
val it: Iterator[Any] = t.productIterator
// while(it.hasNext) println(it.next())
// for (elem <- it) println(elem)
it.foreach(println)
// 根据元素类型来进行后续不同的操作
/*
for (e <- it) {
if(e.isInstanceOf[String]){
val str = e.asInstanceOf[String]
// 可以针对字符串进行后续操作
} else if(e.isInstanceOf[Int]){
val i = e.asInstanceOf[Int]
}
}
*/
}
}
7.元组也可以形成嵌套
// 元组嵌套
val t3 = (("Bob", 15), ("Amy", "female", 14), "Alex", (3, 5, "David"))
println(t3)
println(t3._1._1)
集合
转换
操作一
package com.wph.collection
object CollectionDemo {
def main(args: Array[String]): Unit = {
// 数组 -> 其他
val arr = Array[Int](2, 3, 4, 2, 8, 8, 9)
val arrToList = arr.toList
println(arrToList)
val arrToSet = arr.toSet
println(arrToSet)
// 列表 -> 其他
val list = List[Int](2, 3, 1, 4, 3, 2, 6)
val listToArray = list.toArray
println(listToArray.mkString(", "))
val listToSet = list.toSet
println(listToSet)
// 集合 -> 其他
val set = Set[Int](1, 2, 3, 4, 5)
val setToArray = set.toArray
println(setToArray.mkString(", "))
val setToList = set.toList
println(setToList)
}
}
操作二
package com.wph.collection
object CollectionDemo2 {
def main(args: Array[String]): Unit = {
val map = Map[String, Int]("Bob" -> 15, "Bruce" -> 16, "Bally" -> 17, "Cindy" -> 19, "Canto" -> 16)
// Map -> Array
val mapToArray = map.toArray
println(mapToArray.mkString("\t"))
// Map -> List
val mapToList = map.toList
println(mapToList)
// Map -> Set
val mapToSet = map.toSet
println(mapToSet)
// Array/List/Set如果需要转化为Map,要求其中的元素必须是对偶元组
val list = List[(Int, Int)]((1, 1), (2, 4), (3, 6))
println(list(1)._1)
val listToMap = list.toMap
println(listToMap)
}
}
常用函数
1.衍生子集合
package com.wph.collection
object FunctionDemo {
def main(args: Array[String]): Unit = {
val list = List[Int](2, 1, 4, 7, 8, 5, 6)
val set = Set[Int](2, 1, 4, 7, 8, 5, 6)
// 获取第一个元素
println(list.head)
println(set.head)
// 获取最后一个元素
println(list.last)
println(set.last)
// 去除第一个元素以外的其他元素构成的子集合
println(list.tail)
println(set.tail)
// 去除最后一个元素以外的其他元素构成的子集合
println(list.init)
println(set.init)
// 翻转列表
println(list.reverse)
// 从头部开始,向后获取指定个数的元素,构成子集合返回
println(list.take(3))
println(set.take(3))
// 从尾部开始,向前获取指定个数的元素,构成子集合返回
println(list.takeRight(3))
println(set.takeRight(3))
// 从头部开始,向后删除指定个数的元素,将剩余元素构成子集合返回
println(list.drop(3))
println(set.drop(3))
// 从尾部开始,向前删除指定个数的元素,将剩余元素构成子集合返回
println(list.dropRight(3))
println(set.dropRight(3))
// 从头开始,获取满足条件的元素,直到碰到不满足条件的元素结束,获取到的元素作为子集合返回
println(list.takeWhile(_ < 5))
// 从头开始,删除满足条件的元素,直到碰到不满足条件的元素结束,剩余的元素作为子集合返回
println(list.dropWhile(_ < 5))
}
}
2.衍生集合
package com.wph.collection
object FunctionDemo2 {
def main(args: Array[String]): Unit = {
val number = List[Int](1, 2, 3, 4, 5, 6, 7)
val square = List[Int](1, 4, 9, 16, 25, 36, 49)
// 拉链
// 将两个list合并成一个list,并且能够将元素来一一对应
// (1,1), (2,4), (3,9) ...
// 拉链实际上是将对应位置上的元素合并成一个元组之后,放入一个list中返回
// 如果两个列表元素个数不一样,那么以短的长度来计算
// Seq、Set、Map也可以进行拉链操作!!!
val zipList: List[(Int, Int)] = number.zip(square)
println(zipList)
// 需要将两个list合并成一个Map
val zipMap = number.zip(square).toMap
println(zipMap)
val list = List[Int](2, 6, 4, 8, 7, 9, 1)
val set = Set[Int](2, 6, 4, 8, 7, 9, 1)
// 切分子集合
// 从指定下标开始,将列表切分为2个子列表,放入一个Tuple中返回
// val subLists:Tuple2[List[Int], List[Int]] = list.splitAt(4)
val subLists: (List[Int], List[Int]) = list.splitAt(4)
println(subLists)
println(subLists._1(1))
val subSets: (Set[Int], Set[Int]) = set.splitAt(4)
println(subSets)
// 从集合的集合指定的起始下标开始,切到指定下标结束,不包含指定下标
println(list.slice(1, 4))
println(set.slice(1, 4))
// 滑动函数 - 将集合中固定个数元素进行组合,构成一个新的迭代器
// 0,1,2 1,2,3 2,3,4 ...
list.sliding(3).foreach(println)
set.sliding(3).foreach(println)
// 指定步长的华东
// 0,1,2 2,3,4 4,5,6 ...
list.sliding(3, 2).foreach(println)
set.sliding(3, 2).foreach(println)
}
}
3.reduce和fold操作
package com.wph.collection
object FunctionDemo3 {
def main(args: Array[String]): Unit = {
val list = List[Int](1, 2, 3, 4, 5, 6, 7, 8, 9)
// reduce:规约。将集合中的元素按照指定逻辑进行计算
// 需求:获取集合中所有的元素和
/*
var sum = 0
for (e <- list) sum += e
println(sum)
*/
// 求和:从左到右依次加上每一个元素
// 先计算前两个元素的和,获取结果,然后结果在加上第三个元素,再获取结果,加上下一个元素
// 集合中有5个元素e1~e5
// e1+e2 -> + e3 -> + e4 -> e5
// val sum = list.reduce((x, y) => x + y)
val sum = list.reduce(_ + _)
println(sum)
// 需求:获取集合中所有的元素的积
println(list.reduce(_ * _))
// 等价于
println(list.reduceLeft(_ * _))
// 假设集合中有5个元素:e1~e5
// e4 - e5 -> r => e3 - r -> r => e2 - r -> r => e1 - r
println(list.reduceRight(_ - _))
// fold的操作和reduce操作类似,fold可以指定初始值,在这个初始值的基础上来运算
// reduce就是没有初始值的fold操作
println(list.fold(10)(_ + _))
// 等价
println(list.foldLeft(10)(_ + _))
// 从右开始计算的
println(list.foldRight(10)(_ - _))
// 对集合元素进行集体运算的时候,如果没有初始值,就使用reduce;如果有初始值就使用fold
}
}
4.计算函数
package com.wph.collection
object FunctionDemo4 {
def main(args: Array[String]): Unit = {
val list = List[Int](6, 4, 1, 5, 8, 9, 1, 3, 4)
// 求和
// val sum = list.reduce(_ + _)
val sum = list.sum
println(sum)
// 求积
// val product = list.reduce(_ * _)
val product = list.product
println(product)
// 最大值
println(list.max)
// 最小值
println(list.min)
// 映射:记录的每一个字符出现的次数
// 需求:出现的最大次数对应的字符
val characters = List[(Char, Int)]('a' -> 5, 'c' -> 3, 'd' -> 6, 'e' -> 10, 'f' -> 7, 'i' -> 12, 'm' -> 8)
// 如果集合中存储的是元组,那么默认按照元组的第一个元素来计算大小
// println(characters.max)
println(characters.maxBy(t => t._2))
println(characters.maxBy(_._2))
// 获取出现次数最少的字符
println(characters.minBy(_._2))
// 按照字符的出现次数进行降序排序
println(characters.sortBy(_._2).reverse)
}
}
5.功能函数
package com.wph.collection
object FunctionDemo5 {
def main(args: Array[String]): Unit = {
val names = List("Amy", "Bob", "Alex", "Hack", "David", "Peter", "Alice", "Bruce", "Henry", "Bill", "Bally")
// filter:过滤
// 获取B开头的所有元素
// val filter = names.filter(n => n.startsWith("B"))
val filter = names.filter(_.startsWith("B"))
println(filter)
// map:映射,将元素按照指定规则,转化为指定形式
// 将所有的元素转化为大写
// val map = names.map(e => e.toUpperCase)
val map = names.map(_.toUpperCase)
println(map)
// groupBy:分组,按照指定规则,将元素分为分组
// 按照首字母,将元素分组
// val groupBy = names.groupBy(_.charAt(0))
// println("Amy"(0))
val groupBy: Map[Char, List[String]] = names.groupBy(_(0))
println(groupBy)
// 需求:统计每一个字母开头有多少个名字
// 先分组,就是上面的分组操作
// 将映射由(Char -> List)转化为(Char -> Int)形式
val count = groupBy.map(t => (t._1, t._2.size))
println(count)
// flatten:扁平化。将嵌套的所有的集合中的数据提取出来,形成一个大的集合
val list = List(List(1, 2, 3), List(4, 5), Set(6, 7, 8, 9))
println(list.flatten)
// 将列表中的每一个单词拆分出来,形成新的列表
// String => List[String]
val words = List("hello amy", "hadoop file system", "local system", "hi bob")
// println(words.map(_.split(" ")).flatten)
println(words.flatMap(_.split(" ")))
}
}