scala集合体系
1、Scala中的集合体系主要包括:Iterable、Seq(IndexSeq)、Set(SortedSet)、Map(SortedMap)。其中Iterable是所有集合trait的根trait。实际上Seq、Set、和Map都是子trait
Seq:是一个有先后次序的值的序列,比如数组或列表。IndexSeq允许我们通过整型的下标快速的访问任意元素。举例来说,ArrayBuffer是带下标的,但是链表不是。
Set:是一组没有先后次序的值。在SortedSet中,元素以某种排过序顺序被访问。
Map:是一组(键、值)对偶。SortedMap按照键的排序访问其中的实体。
2、 Scala中的集合是分成可变和不可变两类集合的,其中可变集合就是说,集合的元素可以动态修改,而不可变集合的元素在初始化之后,就无法修改了。分别对应scala.collection.mutable和scala.collection.immutable两个包。
3、Seq下包含了Range、ArrayBuffer、List等子trait。其中Range就代表了一个序列,通常可以使用“1 to 10”这种语法来产生一个Range。 ArrayBuffer就类似于Java中的ArrayList。
一:Seq
Seq主要有两部分组成,IndexSeq和LinearSeq组成
IndexSeq
IndexSeq:是一个有先后次序的值的序列,比如数组或列表。IndexSeq允许我们通过整形的下标快速的访问任意元素。举例来说,ArrayBuffer是带下标的,但是链表不是。IndexSeq中常见集合有:Rang Array String(WrappedString ) Vector NumericRang
val s=IndexedSeq(2,3,4,2,12,3,45,43,56)
这里默认的实现是Vector
这里我们使用List来进行说明。
List是一个这样的集合,是由首元素(head,是这个list的方法)和其余元素组成的子List(tail)构成,除此以外,List还提供了比如isEmpty的基本方法。
一个空列表,通常使用Nil来表示,或者来创建。
构建List,因为是一个trait不能直接创建对象,需要使用其伴生对象来进行。
举个栗子:
object _01CollectionOps {
def main(args: Array[String]): Unit = {
val list = List(1 ,2, 3, 4, 5)
val head = list.head
val tail = list.tail
val isEmpty = list.isEmpty
println("head: " + head)
println("tail: " + tail)
println("isEmpty: " + isEmpty)
//使用递归方式求出list中元素之和
println("sum: " + sum(list))
}
def sum(list:List[Int]):Int = {
if(list.isEmpty) {
0
} else {
list.head + sum(list.tail)
}
}
}
- crud操作
def curdOps: Unit = {
val left = List(1, 2, 3)
val right = List(4, 5, 6, 7)
//查
println("left中的第2个元素:" + left(1))
//遍历
left.foreach(t => print(t + " "))
println("查询:"+list(2))
println("首部增加元素:"+list.::(110))
println("尾部增加元素:"+list.:+(110))
val arr=List(2,3,3)
println("首部增加集合:"+list.:::(arr))
println("尾部增加集合:"+list.++(arr))
println("drop返回删除元素后一个新的集合:"+list.drop(1))
println("dropWhile返回删除元素后一个新的集合:"+list.dropWhile(num => num<5))
println("dropRight返回删除元素后一个新的集合:"+list.dropRight(1))
//判断
println("left.contains(1): " + left.contains(1))
}
二:Set
-
说明
set,是一组没有先后次序的值。在SortedSet中,元素以某种排过序顺序被访问。默认情况下,set集合中的元素不可重复,视图将一个重复元素添加到set中是徒劳的。
-
操作
object _02CollectionOps {
def main(args: Array[String]): Unit = {
val set = SortedSet("abc", "a", "aaa", "acd")
println(set)
println("--------------------------------------------")
val ps = SortedSet(
new Person("cht", 24),
new Person("yyq", 24),
new Person("xlx", 25),
new Person("chq", 29)
)(new Ordering[Person]{
override def compare(x: Person, y: Person) = {
var ret = y.getAge.compareTo(x.getAge)
if(ret == 0) {
ret = y.getName.compareTo(x.getName)
}
ret
}
})
ps.foreach(println)
}
}
/*
编译不能直接通过,No implicit Ordering defined for Person.
其实就已经可以看出,是因为Person不具备比较性或者容器没有提供比较器。
在java中的两个解决方案是Comparable和Comparator,当然同样适用于此,
在scala中建议使用Ordered和Ordering。这两个和java中的是啥关系呢?
trait Ordered extends Comparable with Serializable
trait Ordering extends Comparator with Serializable
*/
class Person(name:String, age:Int) extends Ordered[Person] {
override def toString: String = this.name + "---->" + this.age
override def compare(that: Person) = {
var ret = this.name.compareTo(that.getName)
if(ret == 0) {
ret = this.age.compareTo(that.getAge)
}
ret
}
def getName = name
def getAge = age
}
当既有比较器,又有比较性的时候,比机器其作用。
三:Map
文件:E:/data/hello.txt,内容为
hello you
hello you
hello me
hello you
hello you
hello me
This page outlines the steps for getting a Storm cluster up and running
练习题:统计文件目录下面每个单词的个数—>wordcount。
处理方式一:
val lines = Source.fromFile("E:/data/hello.txt").getLines()
val words = lines.flatMap(line => line.split("\\s+"))
// words.foreach(println)
val map = mutable.Map[String, Int]()
words.foreach(word => {
// val valOption:Option[Int] = map.get(word)
// if(valOption.isDefined) {//有值 Some
// map.put(word, valOption.get + 1)
// } else {//没值 None
// map.put(word, 1)
// }
map.put(word, map.getOrElse(word, 0) + 1)
})
for ((word, count) <- map) {
println(word + "--->" + count)
}
处理方式二:
val lines = Source.fromFile("E:/data/hello.txt").getLines()
val words = lines.flatMap(line => line.split("\\s+"))
//words.foreach(println)
val word2GroupBy:Map[String, List[String]] = words.toList.groupBy(word => word)
//word2GroupBy.foreach(println)
word2GroupBy.map(t => {
val word = t._1
val list = t._2
val size = list.size
(word, size)
}).foreach(println)