Scala集合:Set
Set 是一个不重复元素的无序集合。它不包含重复元素。此外,它不允许通过索引访问一个元素,因为它并没有索引。
下面是一个Set 的例子:
val fruits = Set("apple", "orange", "pear", "banana") val set1 = Set(1,2,3,2,3,4,5,5)
Sets 支持两个基本操作:
- contains:如果set 包含输入参数,则返回true;
- isEmpty:如果set 是空的,返回true;
Set是不重复元素的集合。尝试将已有元素加入进来是没有效果的。比如:
(Set(2,0,1) + 1).foreach(println)
【示例】学习如何使用Scala的不可变Set集合,并执行一些常见的操作,如初始化,添加元素,添加集合,集合的差集和交集,以及创建空集合。
/** * Set是一种数据结构,它允许存储一些值,但这些值不能重复。 */ object SetDemo { def main(args: Array[String]): Unit = { println("1: 初始化一个有3个元素的集合") val set1: Set[String] = Set("苹果","香蕉","葡萄干","苹果") println(s"set1的元素 = $set1") println("\n2: 检查集合中存在的特定元素") println(s"是否有苹果 = ${set1("苹果")}") println(s"是否有香蕉 = ${set1("香蕉")}") println(s"是否有葡萄干 = ${set1("葡萄干")}") println(s"是否有火龙果 = ${set1("火龙果")}") println("\n3: 使用+ 在Set 中添加元素") val set2: Set[String] = set1 + "火龙果" + "葡萄干" println(s"使用 + 向Set集合中添加元素 = $set2") println("\n4: 使用 ++ 将两个Set集合添加到一起") val set3: Set[String] = set1 ++ Set[String]("火龙果", "葡萄干") println(s"使用 ++ 将两个Set集合添加到一起 = $set3") println("\n5: 使用 - 从Set 中删除元素") val set4: Set[String] = set1 - "苹果" println(s"去掉苹果后的Set集合元素 = $set4") println("\n6: 使用& 找到两个集合之间的交集") val set5: Set[String] = Set("火龙果", "香蕉", "苹果") println(s"set1和set5的交集 = ${set1 & set5}") println("\n7: 使用 &~ 找出两个集合的差集") println(s"set1和set5的差集 = ${set1 &~ set5}") println("\n8: 初始化一个空集") val emptySet: Set[String] = Set.empty[String] println(s"Empty Set = $emptySet") } }
Set是一种数据结构,它允许存储一些值,但这些值不能重复。Set不保留元素插入的顺序。默认情况下,Set是以HashSet实现的,其元素根据hashCode方法的值进行组织。
Set(1,2,3,5,7,8).foreach(println)【示例】下面是使用HashSet的示例。
在Scala中,HashSet是Set语义的具体实现。HashSet将使用元素的hashCode作为键,以便在HashSet中快速查找元素的值。学习如何使用Scala的不可变HashSet,并执行一些常见的操作,如初始化、添加元素、添加HashSet、HashSet差集和交集、以及创建空HashSet。
Scala中HashSet的内部数据结构是一个HashTrie,如果你有Java背景,会发现这与Java中的HashTable是不同的。
import scala.collection.immutable.HashSet object HashSetDemo { def main(args: Array[String]): Unit = { println("1: 初始化一个有3个元素的集合") val hashSet1: HashSet[String] = HashSet("苹果","香蕉","葡萄干","苹果") println(s"hashSet1的元素 = $hashSet1") println("\n2: 检查集合中存在的特定元素") println(s"是否有苹果 = ${hashSet1("苹果")}") println(s"是否有香蕉 = ${hashSet1("香蕉")}") println(s"是否有葡萄干 = ${hashSet1("葡萄干")}") println(s"是否有火龙果 = ${hashSet1("火龙果")}") println("\n3: 使用+ 在HashSet 中添加元素") val hashSet2: HashSet[String] = hashSet1 + "火龙果" + "葡萄干" println(s"使用 + 向Set集合中添加元素 = $hashSet2") println("\n4: 使用 ++ 将两个Set集合添加到一起") val hashSet3: HashSet[String] = hashSet1 ++ HashSet[String]("火龙果", "葡萄干") println(s"使用 ++ 将两个Set集合添加到一起 = $hashSet3") println("\n5: 使用 - 从Set 中删除元素") val hashSet4: HashSet[String] = hashSet1 - "苹果" println(s"去掉苹果后的Set集合元素 = $hashSet4") println("\n6: 使用& 找到两个集合之间的交集") val hashSet5: HashSet[String] = HashSet("火龙果", "香蕉", "苹果") println(s"set1和set5的交集 = ${hashSet1 & hashSet5}") println("\n7: 使用 &~ 找出两个集合的差集") println(s"hashSet1和hashSet5的差集 = ${hashSet1 &~ hashSet5}") println("\n8: 初始化一个空集") val emptyHashSet: HashSet[String] = HashSet.empty[String] println(s"Empty Set = $emptyHashSet") } }
LinkedHashSet可以记住元素被插入的顺序。它会维护一个链表来达到这个目的。
val weeks= scala.collection.mutable.LinkedHashSet("Mo","Tu","We","Th","Fr") weeks.foreach(println)
继之前关于HashSet和Set的之后,TreeSet允许存储惟一的元素,但也提供了元素的排序。根据Scala文档,TreeSet内部使用了一个Red-Back数据结构来确保一个平衡的树,为大多数操作提供O(log n)。
【示例】学习如何使用Scala的不可变TreeSet,并执行一些常见的操作,如初始化、添加元素、添加TreeSet、TreeSet差集和交集、排序、创建空的TreeSet。
import scala.collection.immutable.TreeSet /** * 由于正在处理Set语义,因此只存储唯一的和不可重复的值。 */ object TreeSetDemo { def main(args: Array[String]): Unit = { println("1: 初始化一个有3个元素的集合") val treeSet1: TreeSet[String] = TreeSet("苹果","香蕉","葡萄干","苹果") println(s"treeSet1的元素 = $treeSet1") println("\n2: 检查集合中存在的特定元素") println(s"是否有苹果 = ${treeSet1("苹果")}") println(s"是否有香蕉 = ${treeSet1("香蕉")}") println(s"是否有葡萄干 = ${treeSet1("葡萄干")}") println(s"是否有火龙果 = ${treeSet1("火龙果")}") println("\n3: 使用+ 在TreeSet 中添加元素") val treeSet2: TreeSet[String] = treeSet1 + "火龙果" + "葡萄干" println(s"使用 + 向TreeSet集合中添加元素 = $treeSet2") println("\n4: 使用 ++ 将两个Set集合添加到一起") val treeSet3: TreeSet[String] = treeSet1 ++ TreeSet[String]("火龙果", "葡萄干") println(s"使用 ++ 将两个TreeSet集合添加到一起 = $treeSet3") println("\n5: 使用 - 从TreeSet 中删除元素") val treeSet4: TreeSet[String] = treeSet1 - "苹果" println(s"去掉苹果后的Set集合元素 = $treeSet4") println("\n6: 使用& 找到两个集合之间的交集") val treeSet5: TreeSet[String] = TreeSet("火龙果", "香蕉", "苹果") println(s"treeSet1和treeSet5的交集 = ${treeSet1 & treeSet5}") println("\n7: 使用 &~ 找出两个集合的差集") println(s"treeSet1和treeSet5的差集 = ${treeSet1 &~ treeSet5}") println("\n8: 改变TreeSet的顺序为降序字母排列") object AlphabetOrdering extends Ordering[String] { def compare(element1:String, element2:String): Int = element2.compareTo(element1) } val treeSet6: TreeSet[String] = TreeSet("苹果","香蕉","葡萄干")(AlphabetOrdering) println(s"treeSet6的元素 = $treeSet6") println("\n9: 初始化一个空集") val emptyTreeSet: TreeSet[String] = TreeSet.empty[String] println(s"Empty TreeSet = $emptyTreeSet") } }
如果想要按照已排序的顺序来访问其中的元素,使用SortedSet:
scala.collection.immutable.SortedSet(1,2,3,4,5,6).foreach(println)
继前面关于Set、HashSet和TreeSet之后,SortedSet允许存储惟一的元素,但也提供了元素的排序。根据Scala文档,SortedSet是一种特征(trait)。它的具体类实现是讨论过的TreeSet。
【示例】学习如何使用Scala的不可变SortedSet,并执行一些常见的操作,如初始化、添加元素、添加SortedSet、SortedSet的差集和交集、排序和创建空的SortedSet。
import scala.collection.immutable.SortedSet object SortedSetDemo { def main(args: Array[String]): Unit = { println("1: 初始化一个有3个元素的集合") val sortedSet1: SortedSet[String] = SortedSet("苹果","香蕉","葡萄干","苹果") println(s"sortedSet1的元素 = $sortedSet1") println("\n2: 检查集合中存在的特定元素") println(s"是否有苹果 = ${sortedSet1("苹果")}") println(s"是否有香蕉 = ${sortedSet1("香蕉")}") println(s"是否有葡萄干 = ${sortedSet1("葡萄干")}") println(s"是否有火龙果 = ${sortedSet1("火龙果")}") println("\n3: 使用+ 在TreeSet 中添加元素") val sortedSet2: SortedSet[String] = sortedSet1 + "火龙果" + "葡萄干" println(s"使用 + 向SortedSet集合中添加元素 = $sortedSet2") println("\n4: 使用 ++ 将两个Set集合添加到一起") val sortedSet3: SortedSet[String] = sortedSet1 ++ SortedSet[String]("火龙果", "葡萄干") println(s"使用 ++ 将两个SortedSet集合添加到一起 = $sortedSet3") println("\n5: 使用 - 从SortedSet中删除元素") val sortedSet4: SortedSet[String] = sortedSet1 - "苹果" println(s"去掉苹果后的SortedSet集合元素 = $sortedSet4") println("\n6: 使用& 找到两个集合之间的交集") val sortedSet5: SortedSet[String] = SortedSet("火龙果", "香蕉", "苹果") println(s"sortedSet1和sortedSet5的交集 = ${sortedSet1 & sortedSet5}") println("\n7: 使用 &~ 找出两个集合的差集") println(s"sortedSet1和sortedSet5的差集 = ${sortedSet1 &~ sortedSet5}") println("\n8: 改变SortedSet的顺序为降序字母排列") object AlphabetOrdering extends Ordering[String] { def compare(element1:String, element2:String): Int = element2.compareTo(element1) } val sortedSet6: SortedSet[String] = SortedSet("苹果","香蕉","葡萄干")(AlphabetOrdering) println(s"sortedSet6的元素 = $sortedSet6") println("\n9: 初始化一个空集") val emptySortedSet: SortedSet[String] = SortedSet.empty[String] println(s"Empty TreeSet = $emptySortedSet") } }
即可保证顺序,又要保证唯一性,可以使用ListSet类型。
【示例】使用不可变的ListSet。
import scala.collection.immutable.ListSet object ListSetDemo { def main(args: Array[String]): Unit = { println("1:初始化一个不可变的ListSet") // val listSet1: ListSet[String] = ListSet("苹果","香蕉","葡萄干") val listSet1 = ListSet("苹果","香蕉","葡萄干") // 使用类型推断 println(s"listSet1的元素有 = $listSet1") println("\n2: 检查不可变ListSet的元素") println(s"Element 苹果 = ${listSet1("苹果")}") println(s"Element 香蕉 = ${listSet1("香蕉")}") println(s"Element 葡萄干 = ${listSet1("葡萄干")}") println(s"Element 草莓 = ${listSet1("草莓")}") println("\n3: ListSet是一个递归数据结构") println(s"head of listset is = ${listSet1.head}") println(s"tail of listset is = ${listSet1.tail}") println(s"tail of listset is = ${listSet1.tail.head}") println(s"tail of listset is = ${listSet1.tail.tail}") println("\n4: 使用+ 向不可变的ListSet添加元素") // val listSet2: ListSet[String] = listSet1 + "草莓" val listSet2: ListSet[String] = listSet1 + "葡萄干" println(s"在ListSet中添加元素,使用 + = $listSet2") println("\n5: 使用 ++ 将两个ListSet添加到一起") val listSet3: ListSet[String] = listSet1 ++ ListSet("火龙果","苹果") println(s"添加两个列表一起,使用 ++ = $listSet3") println("\n6: 从ListSet删除元素,使用 -") val listSet4: ListSet[String] = listSet1 - "苹果" println(s"没有苹果元素的ListSet = $listSet4") println("\n7: 初始化一个空的ListSet") val emptyListSet: ListSet[String] = ListSet.empty[String] println(s"String类型的空ListSet = $emptyListSet") } }
什么是BitSet?
继之前的Set、HashSet、TreeSet和SortedSet之后,BitSet也允许存储没有可重复值的唯一元素。根据Scala文档,BitSet表示一个小整数的集合,作为一个大整数的位。在本例中,我们将重点关注BitSet的set语义。
【示例】学习如何使用Scala的不可变BitSet,并执行一些常见的操作,如初始化,添加元素,添加BitSet, BitSet差集和交集,以及创建空BitSet。
import scala.collection.immutable.BitSet object BitSetDemo { def main(args: Array[String]): Unit = { println("1: 初始化一个具有3个元素的BitSet") val bitSet1: BitSet = BitSet(3, 2, 0) println(s"bitSet1中的元素 = $bitSet1") println("\n2: 在BitSet中检查特定的元素") println(s"Element 0 = ${bitSet1(0)}") println(s"Element 2 = ${bitSet1(2)}") println(s"Element 3 = ${bitSet1(3)}") println(s"Element 3 = ${bitSet1(1)}") println("\n3: 使用 + 在BitSet中添加元素") val bitSet2: BitSet = bitSet1 + 13 + 13 println(s"使用 + 在BitSet中添加元素 = $bitSet2") println("\n4: 使用++ 将两个BitSet添加到一起") val bitSet3: BitSet = bitSet1 ++ BitSet(13, 14, 15, 16, 17) println(s"使用++ 将两个BitSet添加到一起 = $bitSet3") println("\n5: 使用- 在BitSet中删除元素") val bitSet4: BitSet = bitSet1 - 0 println(s"移除元素0后的BitSet = $bitSet4") println("\n6: 使用& 找到两个BitSet之间的交集") val bitSet5: BitSet = BitSet(0, 2, 4) println(s"bitSet1和bitSet5的交集 = ${bitSet1 & bitSet5}") println("\n7:使用 &~ 找到两个BitSet之间的差集") println(s"bitSet1和bitSet5的差集 = ${bitSet1 &~ bitSet5}") println("\n8: 初始化一个空的 BitSet") val emptyBitSet: BitSet = BitSet.empty println(s"Empty BitSet = $emptyBitSet") } }