十八、Scala的Iterable、Seq、Set、Map集合


1. Iterable

1.1 概述

Iterable代表一个可以迭代的集合,它继承了Traversable特质,同时也是其他集合的父特质。最重要的是,它定义了获取迭代器(iterator)的方法:def iterator:Iterator[A] ,这是一个抽象方法,它的具体实现类需要实现这个方法,从而实现迭代的返回集合中的元素

1.2 分类

Traversable提供了两种遍历数据的方式:

  • iterator()方法:属于主动迭代,我们可以通过hasNext()检查是否还有元素,并且可以主动地调用next()方法获取元素,即我们可以自主地控制迭代过程
  • foreach()方法:属于被动迭代,我们只提供一个函数,并不能控制遍历的过程,即迭代过程是由集合本身控制的

1.3 遍历集合

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

object ClassDemo {
	def main(args:Array[String]):Unit = {
		//1.定义一个列表
		val list = (1 to 5).toList
		//2.通过iterator()方法遍历
		//2.1通过集合对象(list)来获取其对应的迭代器对象
		val it:Iterator[Int] = list.iterator
		//2.2判断是否还有下一个元素,因为不知道集合中有多少个元素,所以采用循环来实现
		while (it.hasNext) {
			//只要能走到这里,说明集合中有元素
			//2.3通过next()方法来获取指定的元素
			val num = it.next()
			println(num) 
		}
		
		//3.通过foreach()方法遍历
		//普通版
		list.foreach((x:Int) => println(x))

		//优化版
		list.foreach(println(_))
	}
}
//1
//2
//3
//4
//5

1.4 分组遍历

如果遇到将Iterable对象中的元素分成固定大小的组,然后遍历这种需求,就可以通过grouped()方法实现。

格式:

def grouped(size:Int):Iterator[Iterable[A]]

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

object ClassDemo {
	def main(args:Array[String]):Unit = {
		//1.定义一个Iterable集合
		val list = (1 to 13).toIterable
		
		//2.对Iterable集合分组
		//方式一:合并版(推荐)
		//2.1获取迭代器对象
		val it = list.grouped(5)
		//2.2判断迭代器中是否有元素
		while (it.hasNext) {
			//2.3如果有,则获取元素,并打印
			val result = it.next()
			println(result)
		}

		//方式二:分解版
		//第一次获取
		val b1 = it.hasNext
		if (b1) {
			val.result1 = it.next()
			println(b1, result1) //(true, Vecotr(1,2,3,4,5))
		//第二次获取
		val b2 = it.hasNext
		if (b2) {
			val.result2 = it.next()
			println(b2, result2) //(true, Vecotr(6,7,8,9,10))
		//第三次获取
		val b3 = it.hasNext
		if (b3) {
			val.result3 = it.next()
			println(b3, result3) //(true, Vecotr(11,12,13))
		}
		
	}
}
//Vecotr(1,2,3,4,5)
//Vecotr(6,7,8,9,10)
//Vecotr(11,12,13)

1.5 按照索引生成元组

Iterable集合中存储的每个元素都是有索引的,如果我们想按照元素 -> 索引这种格式,生成一个新的集合,此时需要用到zipWithIndex()方法。

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

object ClassDemo {
	def main(args:Array[String]):Unit = {
		//1.定义一个Iterable集合
		val list1 = Iterable("A", "B", "C", "D", "E")
		
		//2.通过zipWithIndex()方法,按字符串->索引这种格式,生成新的集合
		val list2:Iterable[(String, Int)] = list1.zipWithIndex

		//3.重新按照 索引->字符串这种格式,生成新的集合
		val list3:Iterable[(Int, String)] = list2.map(x => x._2 -> x._1)
		
		//4.打印结果
		list3.foreach(println(_))
	}
}
//(0,A)
//(1,B)
//(2,C)
//(3,D)
//(4,E)

1.6 判断集合是否相同

有时,我们不仅想判断两个集合中的元素是否全部相同,而且要求这两个集合元素的迭代顺序保持一致,此时用sameElements()方式实现

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

object ClassDemo {
	def main(args:Array[String]):Unit = {
		//1.定义一个Iterable集合
		val list1 = Iterable("A", "B", "C")
		
		//2.通过sameElements()方法,判断list1和Iterable("A", "B", "C")集合是否相同
		println(list1.sameElements(Iterable("A", "B", "C"))) //true

		//3.通过sameElements()方法,判断list1和Iterable("A", "C", "B")集合是否相同
		println(list1.sameElements(Iterable("A", "C", "B"))) //false
		
		//4.通过sameElements()方法,判断list1和list2是否相同
		val list2 = Iterable("A", "B", "C", "D")
		println(list1.sameElements(list2))) //false
	}
}
//

2. Seq

2.1 概述

Seq特质代表按照一定顺序排列的元素序列,序列是一种特别的可迭代集合,它的元素特点是有序(元素存取顺序一致),可重复,有索引

2.2 分类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 创建Seq集合

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

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val s1 = (1 to 5).toSeq
		print(s1)
	}
}
//Range(1,2,3,4,5)

2.4 获取长度及元素

因为Seq集合的每个元素都是有索引的,所以我们可以通过索引直接获取其对应的元素,而且通过length()size()方法获取集合的长度

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

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val s1 = (1 to 5).toSeq
		//打印长度
		println(s1.length, s1.size) //(5, 5)
		//获取索引为2的元素
		//方式一:通过集合名(索引)的方式实现
		println(s1(2)) //3
		//方式二:通过集合的伴生对象的apply()方法实现
		println(s1.apply(2)) //3
	}
}

2.5 获取指定元素的索引值

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

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

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val s1 = Seq(1, 2, 4, 6, 4, 3, 2)
		println(s1.indexOf(2)) //1
		println(s1.lastIndexOf(2)) //6
		println(s1.indexWhere(x => x < 5 && x % 2 == 0)) //1
		println(s1.indexWhere(x => x < 5 && x % 2 == 0, 2)) //4
		println(s1.lastIndexWhere(x => x < 5 && x % 2 == 0)) //6
		println(s1.indexOfSlice(Seq(1,2))) //0
		println(s1.indexOfSlice(Seq(1,2), 3)) //-1	
	}
}

2.6 判断是否包含指定数据

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

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

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val s1 = (1 to 10).toSeq
		println(s1.startsWith(Seq(1,2))) //true
		println(s1.startsWith(Seq(1,3))) //false
		println(s1.endsWith(Seq(9,10))) //true
		println(s1.endsWith(Seq(8,9))) //false
		println(s1.contains(3) //true
		println(s1.containsSlice(Seq(1,2))) //true
		println(s1.containsSlice(Seq(1,3)))  //false	
	}
}

2.7 修改指定的元素

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

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

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val s1 = (1 to 5).toSeq
		println(s1) //Range(1,2,3,4,5)
		
		val s2 = s1.update(2, 10)
		println(s2) //Vector(1,2,10,4,5)
		
		/*
			第一个参数:起始索引
			第二个参数:替换后的元素
			第三个参数:替换几个
		*/
		val s3 = s1.patch(1, Seq(10, 20), 3)
		println(s3) //Vector(1,10,20,5)
	}
}

3. Stack

3.1 概述

栈的元素特点是先进后出。由于历史原因,Scala当前的库中还包含一个immutable.Stack,但当前已标记为弃用,因为设计不优雅且性能不佳。因为栈设计大量元素的进出,常用的还是可变栈,例如mutable.Stack, mutable.ArrayStack

在这里插入图片描述

3.2 常用方法

在这里插入图片描述

3.3 演示Stack可变栈

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

import scala.collection.mutable

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val s1 = mutable.Stack(1,2,3,4,5)
		println(s1) //Stack(1,2,3,4,5)
		
		println(s1.top) //1
		println(s1.push(6)) //Stack(6,1,2,3,4,5)
		println(s1.pushAll(Seq(11,22,33))) //Stack(33,22,11,6,1,2,3,4,5)
		println(s1.pop()) //33
		s1.clear()
		println(s1) //stack()
	}
}

3.4 演示ArrayStack可变栈

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

import scala.collection.mutable

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val s1 = mutable.ArrayStack(1,2,3,4,5)
		println(s1) //ArrayStack(1,2,3,4,5)
		
		s1.dup()
		println(s1) //ArrayStack(1,1,2,3,4,5)
		s1.preserving({
			//当该方法中的内容执行完毕后,栈中的数据会恢复
			s1.clear()
			println('hi')
		}) //hi
		println(s1) //ArrayStack(1,2,3,4,5)
	}
}

4. Queue

4.1 概述

队列的元素特点是先进先出,常用的队列是可变队列:mutable.Queue,它内部是以MutableList数据结构实现的。

在这里插入图片描述

4.2 常用方法

在这里插入图片描述

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

import scala.collection.mutable

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val q1 = mutable.Queue(1,2,3,4,5)
		println(q1) //Queue(1,2,3,4,5)
		
		q1.enqueue(6)
		println(q1) //Queue(1,2,3,4,5,6)
		q1.enqueue(7,8,9)
		println(q1) //Queue(1,2,3,4,5,6,7,8,9)
		println(q1.dequeue()) //1
		println(q1.dequeueFirst(_ % 2 != 0)) //Some(3)
		println(q1.dequeueAll(_ % 2 == 0)) //ArrayBuffer(2,4,6,8)
		println(q1) //Queue(5,7,9)
	}
}

5. Set

5.1 概述

Set集合中的元素不包含重复的元素

5.2 分类

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

import scala.collection.{SortedSet, mutable}

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val s1 = SortedSet(1,4,3,2,5)
		println(s1) //TreeSet(1,2,3,4,5)
		
		val s2 = mutable.HashSet(1,4,3,2,5)
		println(s2) //Set(1,5,2,3,4)

		val s3 = mutale.LinkedHashSet(1,4,3,2,5)
		println(s3) //Set(1,4,3,2,5)
	}
}

6. Map

6.1 概述

Map表示映射,包含键值对的集合,基本操作类似于Set集合的操作。

6.2 分类

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

import scala.collection.{SortedSet, mutable}

object ClassDemo {
	def main(args:Array[String]):Unit = {
		val m1 = Map('A' -> 1, 'B' -> 2, 'C' -> 3)
		
		//遍历
		//方式一:通过普通for循环实现
		for((k,v) <- map) println(k,v)
		//(A,1)
		//(B,2)
		//(C,3)
		//方式二:通过foreach函数实现
		map.foreach(println(_))
		//(A,1)
		//(B,2)
		//(C,3)

		println(map.filterKeys(_ == 'B')) //Map(B -> 2)
	}
}

7. 案例:统计字符个数

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

步骤:
在这里插入图片描述

import scala.collection.mutable
import scala.io.StdIn

object ClassDemo {
	def main(args:Array[String]):Unit = {
		//1.提示用户录入字符串,并接收
		println('请录入一个字符串:')
		val str = StdIn.readLine()
		//2.定义Map集合,用来存储字符及其出现的次数
		val map = mutable.Map[Char, Int]()
		//3.将字符串转成字符数组
		val chs = str.toCharArray
		//4.遍历字符数组,获取每一个字符
		for(k <- chs) {
			//5.1如果字符是第一次出现,就将其次数记录为1
			if (map.contains(k)) {
				map += (k -> 1)
			} else {
			//5.2如果字符是重复出现,就将其次数+1,然后重新存储
				map += (k -> (map.getOrElse(k, 1) + 1))
			}
		}
		//6.遍历集合,查看结果
		map.foreach(println(_))
	}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值