Scala 编程—第四节:集合操作(List、Set、Map、Tuple、Option)

1.列表

1.1 List定义及特点

// 字符串类型List
scala> val language = List("java", "scala", "python")
language: List[String] = List(java, scala, python)

// 前一个语句与下面语句等同
scala> val language = List.apply("java", "scala", "python")
language: List[String] = List(java, scala, python)

// 数值类型List
scala> val nums = List(1, 2, 3, 4, 5)
nums: List[Int] = List(1, 2, 3, 4, 5)

// 多重List,List的子元素为List
scala> val multiList = List(List(1, 2, 3), List(4, 5, 6))
multiList: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6))

// 遍历List
scala> for (i <- nums) println("i = " + i)
i = 1
i = 2
i = 3
i = 4
i = 5

List与Array有着诸多的相似之处,但它们有两个明显的区别:

  • List一但创建,其值不能被改变
scala> nums(0) = 0
<console>:15: error: value update is not a member of List[Int]
       nums(0) = 0
       ^
  • List具有递归结构(Recursive Structure),例如链表结构
    List类型和其它类型集合一样,它具有协变性(Covariant),即对于类型S和T,如果S是T的子类型,则List[S]也是List[T]的子类型
    例如:
scala> var listStr:List[Object]=List("This","Is","Covariant","Example")
listStr: List[Object] = List(This, Is, Covariant, Example)

// 空的List,其类型为Nothing,Nothing在Scala的继承层次中的最低层
// 即Nothing是任何Scala其它类型如String,Object等的子类
scala> var listStr=List()
listStr: List[Nothing] = List()

scala> var listStr:List[String]=List()
listStr: List[String] = List()

##1.2 List常用构造方法

// 采用::及Nil进行列表构建
scala> val nums = 1 :: (2 :: (3 :: (4 :: Nil)))
nums: List[Int] = List(1, 2, 3, 4)

// 由于::操作符的优先级是从右往左的,因此上一条语句等同于下面这条语句
scala> val nums = 1::2::3::4::Nil
nums: List[Int] = List(1, 2, 3, 4)

1.3 List常用操作

scala> val nums = List(1, 2, 3, 4, 5)
nums: List[Int] = List(1, 2, 3, 4, 5)

// 判断list是否为空
scala> nums.isEmpty
res31: Boolean = false

// 获取第一个元素
scala> nums.head
res32: Int = 1

// 取除第一个元素外剩余的元素,返回的是列表
scala> nums.tail
res33: List[Int] = List(2, 3, 4, 5)

// 取第二个元素
scala> nums.tail.head
res35: Int = 2

// List 连接
// 使用 ::: 运算符
scala> List(1, 2, 3) ::: List(4, 5, 6)
res66: List[Int] = List(1, 2, 3, 4, 5, 6)
// 使用 List.:::() 方法
scala> List(1, 2, 3).:::(List(4, 5, 6))
res67: List[Int] = List(4, 5, 6, 1, 2, 3)
// 使用 concat 方法
scala> List.concat(List(1, 2, 3), (List(4, 5, 6)))
res68: List[Int] = List(1, 2, 3, 4, 5, 6)

// 取除最后一个元素外的元素,返回的是列表
scala> nums.init
res37: List[Int] = List(1, 2, 3, 4)

// 获取最后一个元素
scala> nums.last
res38: Int = 5

// 列表元素倒置
scala> nums.reverse
res39: List[Int] = List(5, 4, 3, 2, 1)

// 丢弃前n个元素
scala> nums drop 2
res40: List[Int] = List(3, 4, 5)

// 获取前n个元素
scala> nums take 1
res41: List[Int] = List(1)

// 在列表开头添加元素
scala> 1 :: List(2, 3)
res69: List[Int] = List(1, 2, 3)

// 将列表进行分割 
scala> nums.splitAt(3)
res42: (List[Int], List[Int]) = (List(1, 2, 3),List(4, 5))
// 等同上一句
scala> (nums.take(3), nums.drop(3))
res43: (List[Int], List[Int]) = (List(1, 2, 3),List(4, 5))

// 拉链操作
scala> val chars = List('1', '2', '3', '4', '5')
chars: List[Char] = List(1, 2, 3, 4, 5)

// 返回的是一个类型为元祖的List
scala> nums zip chars
res45: List[(Int, Char)] = List((1,1), (2,2), (3,3), (4,4), (5,5))

// List toString
scala> nums.toString
res46: String = List(1, 2, 3, 4, 5)

// List mkString
scala> nums.mkString
res47: String = 12345

// 转换成数组
scala> nums.toArray
res48: Array[Int] = Array(1, 2, 3, 4, 5)

// range方法,构建某一值范围内的List
scala> List.range(6, 10)
res51: List[Int] = List(6, 7, 8, 9)

// 步长为2
scala> List.range(1, 10, 2)
res52: List[Int] = List(1, 3, 5, 7, 9)

// 步长为-1
scala> List.range(1, 10, -1)
res53: List[Int] = List()

// 创建一个指定重复数量的元素列表
scala> List.fill(3)("hello")
res61: List[String] = List(hello, hello, hello)

// 通过给定的函数来创建列表
// 方法的第一个参数为元素的数量,可以是二维的,第二个参数为指定的函数
// 通过指定的函数计算结果并返回值插入到列表中,起始值为 0
scala> List.tabulate(6)(n => n * n)
res62: List[Int] = List(0, 1, 4, 9, 16, 25)

scala> List.tabulate(3, 4)(_ * _)
res63: List[List[Int]] = List(List(0, 0, 0, 0), List(0, 1, 2, 3), List(0, 2, 4, 6))

2.Set 无序集合

      Set(集合)是没有重复的对象集合,所有的元素都是唯一的。Set集合分为可变的和不可变的集合。
      可变的集合可以更新或修改,添加、删除、修改元素将作用于原集合,不可变集合一量被创建,便不能被改变,添加、删除、更新操作返回的是新的集合,老集合保持不变。
      默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包。默认引用 scala.collection.immutable.Set

2.1 不可变Set

// 创建不可变Set
scala> val set = Set(1, 2, 3, 4, 5)
set: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)

// set 类型
scala> println(set.getClass.getName)
scala.collection.immutable.HashSet$HashTrieSet

// 集合中是否存在模2等于0的数
scala> println(set.exists(_ % 2 == 0))

2.2 可变Set

// 引入包
scala> import scala.collection.mutable.Set
import scala.collection.mutable.Set

// 创建可变即可
scala> val mutableSet = Set(5, 8, 2, 0, 1)
mutableSet: scala.collection.mutable.Set[Int] = Set(0, 1, 5, 2, 8)

// 查看类型
scala> mutableSet.getClass.getName
res11: String = scala.collection.mutable.HashSet

// 添加元素
scala> mutableSet.add(7)
res12: Boolean = true

// set 集合元素无序
scala> mutableSet
res13: scala.collection.mutable.Set[Int] = Set(0, 1, 5, 2, 7, 8)

// 删除元素
scala> mutableSet.remove(7)
res14: Boolean = true

// set 集合元素无序
scala> mutableSet
res15: scala.collection.mutable.Set[Int] = Set(0, 1, 5, 2, 8)

// 添加元素,元素重复,不会添加
scala> mutableSet += 5
res16: mutableSet.type = Set(0, 1, 5, 2, 8)

scala> mutableSet += 9
res17: mutableSet.type = Set(0, 9, 1, 5, 2, 8)

// 删除元素
scala> mutableSet -= 9
res18: mutableSet.type = Set(0, 1, 5, 2, 8)

**注:**虽然可变Set和不可变Set都有添加或删除元素的操作,但是有一个非常大的差别。对不可变Set进行操作,会产生一个新的set,原来的set并没有改变,这与List一样。 而对可变Set进行操作,改变的是该Set本身,与ListBuffer类似。

2.3 集合常用操作

scala> val language = Set("java", "scala", "python")
language: scala.collection.mutable.Set[String] = Set(python, java, scala)

scala> val nums: Set[Int] = Set()
nums: scala.collection.mutable.Set[Int] = Set()

// head 返回集合第一个元素
scala> language.head
res19: String = python

// tail 返回一个集合,包含除了第一元素之外的其他元素
scala> language.tail
res20: scala.collection.mutable.Set[String] = Set(java, scala)

// isEmpty 在集合为空时返回true
scala> language.isEmpty
res22: Boolean = false

scala> nums.isEmpty
res23: Boolean = true

// 连接
scala> val rdbmdb = Set("mysql", "sqlserver", "oracle")
rdbmdb: scala.collection.mutable.Set[String] = Set(mysql, sqlserver, oracle)

scala> val nosqldb = Set("redis", "mongodb")
nosqldb: scala.collection.mutable.Set[String] = Set(redis, mongodb)

scala> val dbs = rdbmdb ++ nosqldb
dbs: scala.collection.mutable.Set[String] = Set(redis, mysql, mongodb, sqlserver, oracle)

// 交集
scala> val num1 = Set(12, 9, 8, 17, 0)
num1: scala.collection.mutable.Set[Int] = Set(0, 12, 9, 17, 8)

scala> val num2 = Set(2, 5, 10, 8, 4)
num2: scala.collection.mutable.Set[Int] = Set(5, 2, 10, 4, 8)

scala> num1.&(num2)
res25: scala.collection.mutable.Set[Int] = Set(8)

// 最大值
scala> num1.max
res26: Int = 17

// 最小值
scala> num1.min
res27: Int = 0

// 求和
scala> num1.sum
res28: Int = 46

// 遍历
scala> for(i <- num1) println("i = " + i)
i = 0
i = 12
i = 9
i = 17
i = 8

3. Map 键值对

      Map是一种键值对的集合,一般将其翻译为映射,也叫哈希表(Hash tables)。Map 中的键都是唯一的。
      Map 有两种类型,可变与不可变,区别在于可变对象可以修改它,而不可变对象不可以。
      默认情况下 Scala 使用不可变 Map。如果需要使用可变集合,需要显式的引入 import scala.collection.mutable.Map 类

3.1 不可变Map

scala> var map:Map[String, String] = Map()
map: Map[String,String] = Map()

scala> val userInfo = Map("name" -> "zhangsan", "age" -> 18, "address" -> "BeiJing")
userInfo: scala.collection.immutable.Map[String,Any] = Map(name -> zhangsan, age -> 18, address -> BeiJing)

3.2 可变Map

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

scala> val userInfo = Map("name" -> "zhangsan", "age" -> 18, "address" -> "BeiJing")
userInfo: scala.collection.mutable.Map[String,Any] = Map(address -> BeiJing, age -> 18, name -> zhangsan)

// 初始化Map,也可以通过 ("name", "zhangsan") 这种方式实现(元组的形式)
scala> val userInfo = Map(("name", "zhangsan"), ("age", 18), ("address", "BeiJing"))
userInfo: scala.collection.mutable.Map[String,Any] = Map(address -> BeiJing, age -> 18, name -> zhangsan)

// 如果是不可变map执行会报错
scala> userInfo.clear()

scala> userInfo
res31: scala.collection.mutable.Map[String,Any] = Map()

3.3 Map常用操作

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

scala> val userInfo = Map("name" -> "zhangsan", "age" -> 18, "address" -> "BeiJing")
userInfo: scala.collection.mutable.Map[String,Any] = Map(address -> BeiJing, age -> 18, name -> zhangsan)

// 判断键知否存在
scala> userInfo.contains("name")
res39: Boolean = true

scala> userInfo.contains("job")
res40: Boolean = false

// 获取所有键
scala> userInfo.keys
res33: Iterable[String] = Set(address, age, name)

// 获取所有值
scala> userInfo.values
res34: Iterable[Any] = HashMap(BeiJing, 18, zhangsan)

// 集合是否为空
scala> userInfo.isEmpty
res36: Boolean = false

// 清空集合
scala> userInfo.clear

scala> userInfo.isEmpty
res38: Boolean = true

// Map 合并
scala> val map1 = Map("math" -> 68, "chinese" -> 90)
map1: scala.collection.mutable.Map[String,Int] = Map(chinese -> 90, math -> 68)

scala> val map2 = Map("english" -> 99)
map2: scala.collection.mutable.Map[String,Int] = Map(english -> 99)

scala> map1 ++ map2
res41: scala.collection.mutable.Map[String,Int] = Map(chinese -> 90, math -> 68, english -> 99)

scala> map1.++(map2)
res42: scala.collection.mutable.Map[String,Int] = Map(chinese -> 90, math -> 68, english -> 99)

// 添加元素
scala> map2("music") = 89

scala> map2.put("computer", 91)
res46: Option[Int] = None

// Map 遍历操作1
scala> for( i <- map2) println(i)
(computer,91)
(music,89)
(english,99)

// Map 遍历操作2
scala> map2.foreach(m => {val (k, v) = m; println(k + ":" + v)})
computer:91
music:89
english:99

// Map 遍历操作3
scala> map2.foreach(m => println(m._1 + ":" + m._2))
computer:91
music:89
english:99

// Map 遍历操作4
scala> map2.keys.foreach{ i => println("k" + i + " = " + map2(i))}
kcomputer = 91
kmusic = 89
kenglish = 99

// 获取元素
scala> map2.get("music")
res48: Option[Int] = Some(89)

scala> map2.get("computer")
res49: Option[Int] = Some(91)

scala> map2.get("sports")
res50: Option[Int] = None

4. 元祖 Tuple

       与列表一样,元组也是不可变的,但与列表不同的是元组可以包含不同类型的元素前面我们提到Map是键值对的集合,元组则是不同类型值的聚集

元祖创建及操作

// 创建元祖
// 方式1
scala> val tup = (1, 3.14, 1.11F, "test")
tup: (Int, Double, Float, String) = (1,3.14,1.11,test)
// 方式2
scala> val tup = new Tuple4(1, 3.14, 1.11F, "test")
tup: (Int, Double, Float, String) = (1,3.14,1.11,test)

元组的实际类型取决于它的元素的类型,如上面所创建的元祖,使用第二种方式创建元祖的时候需要指定元祖元素的数量,目前 Scala 支持的元组最大长度为 22。对于更大长度你可以使用集合,或者扩展元组

// 访问元祖元素,元素下标从1开始
scala> tup._1
res59: Int = 1

scala> tup._2
res60: Double = 3.14

// 元祖转为字符串
scala> tup.toString
res61: String = (1,3.14,1.11,test)

//  迭代元祖
scala> tup.productIterator.foreach{ i => println("i = " + i) }
i = 1
i = 3.14
i = 1.11
i = test

// 元祖元素交换
scala> val tup = ("java", "python")
tup: (String, String) = (java,python)

scala> tup.swap
res67: (String, String) = (python,java)

5. 选项 Option

       Scala Option(选项)类型用来表示一个值是可选的(有值或无值)。
       Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 。

// scala中声明的变量都不需要显式制定类型,但在实际开发中还是建议显示指定,这样可读性较好
scala> val map: Map[String, String] = Map("name" -> "tom", "job" -> "IT")
map: scala.collection.mutable.Map[String,String] = Map(name -> tom, job -> IT)

scala> val value1: Option[String] = map.get("name")
value1: Option[String] = Some(tom)

scala> val value2: Option[String] = map.get("address")
value2: Option[String] = None

       上面代码中map是一个key,value均为String类型的hash map,但不一样的是他的 get() 返回的是一个叫 Option[String] 的类别。
       Scala 使用 Option[String] 来告诉你:「我会想办法回传一个 String,但也可能没有 String 给你」。
       map 里并没有 key2 这个数据,get() 方法返回 None。
       Option 有两个子类别,一个是 Some,一个是 None,当他回传 Some 的时候,代表这个函式成功地给了你一个 String,而你可以通过 get() 这个函式拿到那个 String,如果他返回的是 None,则代表没有字符串可以给你

       其实在我们实际使用时,不需要返回Some(tom)或None,我们需要返回具体的值,如果有值就返回值,没有值,设定一个指定值,这种情况下可以使用模式匹配来输出匹配值

scala> def show(v: Option[String]) = v match {
     | case Some(s) => s
     | case None => "?"
     | }
show: (v: Option[String])String

scala> show(map.get("name"))
res0: String = tom

scala> show(map.get("address"))
res1: String = ?
// 除了上面的模式匹配还可以使用 getOrElse() 方法来获取元组中存在的元素或者使用其默认的值
scala> map.get("name").getOrElse("?")
res2: String = tom

scala> map.get("address").getOrElse("?")
res3: String = ?
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值