HashSet
To use the HashSet
type, you need to import the collection
package.
import std.collection.*
You can use the HashSet
type to construct a collection that contains only unique elements.
HashSet
is a generic type, hence Cangjie uses HashSet<T>
to denote it, where T
is the element type of the HashSet
. T
must be a type that implements the Hashable
and Equatable<T>
interfaces, e.g. a numeric type or String
, or a type variable with the respective constraints.
var a: HashSet<Int64> = ... // HashSet whose element type is Int64
var b: HashSet<String> = ... // HashSet whose element type is String
Two HashSet
instantiations with different element types are different types and their values cannot be "cross-assigned". Continuing the last example, the following code is invalid.
b = a // Type mismatch
In Cangjie, you use a constructor to create a HashSet
with a particular element type. The different constructors enable you to pre-allocate storage and/or initialize the elements.
// Create an empty HashSet of strings:
let a = HashSet<String>()
// Create an empty HashSet with the initial capacity of 100:
let b = HashSet<String>(100)
// Create a HashSet of Int64 integers, containing elements 0 and 1 (no duplicates):
let c = HashSet<Int64>([0, 1, 0])
// Use another collection to initialize a HashSet:
let d = HashSet<Int64>(c)
// Create a HashSet of Int64 integers and add 10 elements to it using a rule function:
let e = HashSet<Int64>(10, {x: Int64 => (x * x)})
Accessing HashSet Members
When you need to access each element of a HashSet
, you can use the for-in
loop expression for traversal.
import std.collection.*
main() {
let mySet = HashSet<Int64>([0, 1, 2])
for (i in mySet) {
println("The element is ${i}")
}
}
It should be noted that HashSet
does not guarantee that its elements are arranged in the order in which they were inserted, or in any other particular order. Therefore, the order of traversal may be different from that of insertion.
With that in mind, compiling and executing the above code will output the following lines:
The element is 0
The element is 1
The element is 2
but not necessarily in the same order as above.
When you need to know the number of elements in a HashSet
, you can use its size
property to obtain that information:
import std.collection.*
main() {
let mySet = HashSet<Int64>([0, 1, 2, 1])
if (mySet.size == 0) {
println("This is an empty hashset")
} else {
println("The size of hashset is ${mySet.size}")
}
}
Compiling and executing the above code outputs the following information:
The size of hashset is 3
because, again, a HashSet
contains no duplicates.
When you want to determine whether a particular value v
is present among the elements of a HashSet
, you can use its contains
member function. If such an element exists, contains(v)
returns true
, otherwise, it returns false
.
let mySet = HashSet<Int64>([0, 1, 2])
let a = mySet.contains(0) // a == true
let b = mySet.contains(-1) // b == false
Modifying a HashSet
HashSet
is a mutable reference type. It provides functions for adding and removing elements.
To add a single element to a HashSet
, use its put
member function. If you want to add multiple elements at the same time, you can use the putAll
member function, which accepts another collection type (for example, Array
) with the same element type. If the element is not already present in the HashSet
, the put
function adds it. Otherwise, the put
function has no effect.
let mySet = HashSet<Int64>() // mySet is empty
mySet.put(0) // mySet contains element 0
mySet.put(0) // mySet still contains only element 0
mySet.put(1) // mySet contains elements 0, 1
let li = [2, 3]
mySet.putAll(li) // mySet contains elements 0, 1, 2, 3
HashSet
is a reference type. When a HashSet
instance is used as an expression, no copying occurs. All references to the same HashSet
instance share the same data.
Therefore, modifications of a HashSet
affect all references to that instance.
let set1 = HashSet<Int64>([0, 1, 2])
let set2 = set1
set2.put(3)
// set1 contains elements 0, 1, 2, 3
// set2 contains elements 0, 1, 2, 3
To delete an element from a HashSet
, you can use the remove
member function to specify the element to be deleted. If there is no such element, remove
has no effect.
let mySet = HashSet<Int64>([0, 1, 2, 3])
mySet.remove(1) // mySet contains elements 0, 2, 3