Scala:Set

来源:互联网 发布:应用下载软件 编辑:程序博客网 时间:2024/06/06 20:00

Scala开篇(目录)

Set集合类型,各种语言都有,用它来存储不重复的数据元素。因为它也属于集合类型,所以它的很多操作都和Array差不多(Array(集合、序列))或者参考官方文档,所以这里就不重点讲关于set的操作,我们主要来看一下它的内部实现。

Set是trait类型,它的声明很简单

trait Set[A] extends Iterable[A]                with scala.collection.Set[A]                with GenericSetTemplate[A, Set]                with SetLike[A, Set[A]]                with Parallelizable[A, ParSet[A]]{  override def companion: GenericCompanion[Set] = Set    override def toSet[B >: A]: Set[B] = to[({type l[a] = immutable.Set[B]})#l] // for bincompat; remove in dev    override def seq: Set[A] = this  protected override def parCombiner = ParSet.newCombiner[A] // if `immutable.SetLike` gets introduced, please move this there!}

如果你要想实现自己的set类型,需要实现下面的方法

def contains(key: A): Booleandef iterator: Iterator[A]def +(elem: A): Thisdef -(elem: A): This

Set1,Set2,Set3,Set4

在set源码中,定义了Set1,Set2,Set3,Set4,它们分别代表1个,2个,3个,4个元素的set集合,当我们声明的set变量中的元素不多于4个的时候,编译器将分别用上面四个类型创建对象

    var set_1 = Set(1)    var set_2 = Set(1,2)    var set_3 = Set(1,2,3)    var set_4 = Set(1,2,3,4)    println(set_1.getClass.getName)    println(set_2.getClass.getName)    println(set_3.getClass.getName)    println(set_4.getClass.getName)    /**    scala.collection.immutable.Set$Set1    scala.collection.immutable.Set$Set2    scala.collection.immutable.Set$Set3    scala.collection.immutable.Set$Set4    */

当我们用如下代码对其操作时

    var set_1 = Set(1)    set_1 = set_1+2    println(set_1.getClass.getName)    /**    scala.collection.immutable.Set$Set2    */

我们发现set_1的类型变成了Set2,怎么变的?在源代码中是这样体现的

  class Set1[A] private[collection] (elem1: A) extends AbstractSet[A] with Set[A] with Serializable {    override def size: Int = 1    def contains(elem: A): Boolean =      elem == elem1      /**      通过 + 操作符,先判断是否包含要添加的元素,如果包含,直接返回自己,不会重复添加      如果不包括,因为元素增加了,所以要扩容为2个元素的set类型,所以new一个Set2类型      */    def + (elem: A): Set[A] =      if (contains(elem)) this      else new Set2(elem1, elem)    ......}

对于Set2变Set3,Set3变Set4都是一样,当Set4类型增加元素时,他会变为HashSet类型

  class Set4[A] private[collection] (elem1: A, elem2: A, elem3: A, elem4: A) extends AbstractSet[A] with Set[A] with Serializable {    override def size: Int = 4    def contains(elem: A): Boolean =      elem == elem1 || elem == elem2 || elem == elem3 || elem == elem4    def + (elem: A): Set[A] =      if (contains(elem)) this      //这里,new一个HashSet类型对象      else new HashSet[A] + (elem1, elem2, elem3, elem4, elem)    ......  }

几个常用的操作

合并集合(重复数据会被忽略)

val setA = Set(1,2)val setB = Set(3,4)val setC = setA ++ setBprintln(setC.toList.mkString(","))      /**1,2,3,4*///或者val setC = setA + (3,4)//或者val setC = setA + 3 + 4

求交集(&)

val setA = Set(1,2,3,4)val setB = Set(3,4,5)val setC = setA & setBprintln(setC.toList.mkString(","))/**3,4*/

求一个集合中不在另一个集合中的元素(&~)

val setA = Set(1,2,3,4)val setB = Set(3,4,5)val setC = setA &~ setBprintln(setC.toList.mkString(","))/**1,2*/

迭代所有的子集合subsets

val setA = Set(1,2,3,4)println(setA.subsets().toList.mkString("\n"))/**打印结果Set()Set(1)Set(2)Set(3)Set(4)Set(1, 2)Set(1, 3)Set(1, 4)Set(2, 3)Set(2, 4)Set(3, 4)Set(1, 2, 3)Set(1, 2, 4)Set(1, 3, 4)Set(2, 3, 4)Set(1, 2, 3, 4)*/

只列出指定数量元素的子集合subsets(len: Int)

val setA = Set(1,2,3,4)println(setA.subsets(2).toList.mkString("\n"))/**Set(1, 2)Set(1, 3)Set(1, 4)Set(2, 3)Set(2, 4)Set(3, 4)*/
0 0
原创粉丝点击