Just like List, Set also has the following two variants in Kotlin:
- Set
- MutableSet
Set is read-only and MutableSet is the mutable version of Set, which contains the read-write functionalities.
Sets in collections represent mathematical sets (as in set theory).
The following is an example with MutableSet:
fun main(args: Array<String>) { val set = mutableSetOf(1,2,3,3,2) println("set $set") set.add(4) set.add(5) set.add(5) set.add(6) println("set $set") }
The following is the output:
The output clearly shows that, even though we added multiple duplicate items to the set, both at the time of initialization and later, only unique items got inserted and all duplicate items got ignored.
Now, you may be curious as to whether the same will happen with custom classes and data classes; let us check with the following example:
data class MyDataClass (val someNumericValue:Int, val someStringValue:String)
class MyCustomClass (val someNumericValue:Int, val someStringValue:String) {
override fun toString(): String {
return "MyCustomClass(someNumericValue=$someNumericValue, someStringValue=$someStringValue)"
}
}
fun main(args: Array<String>) {
val dataClassSet = setOf(
MyDataClass(1,"1st obj"),
MyDataClass(2,"2nd obj"),
MyDataClass(3,"3rd obj"),
MyDataClass(2,"2nd obj"),
MyDataClass(4,"4th obj"),
MyDataClass(5,"5th obj"),
MyDataClass(2,"will be added"),
MyDataClass(3,"3rd obj")
)
println("Printing items of dataClassSet one by one")
for(item in dataClassSet) {
println(item)
}
val customClassSet = setOf(
MyCustomClass(1,"1st obj"),
MyCustomClass(2,"2nd obj"),
MyCustomClass(3,"3rd obj"),
MyCustomClass(2,"2nd obj"),
MyCustomClass(4,"4th obj"),
MyCustomClass(5,"5th obj"),
MyCustomClass(5,"5th Obj"),
MyCustomClass(3,"3rd obj")
)
println("Printing items of customClassSet one by one")
for(item in customClassSet) {
println(item)
}
}
In this program, we first created a data class and a custom class, then we created sets with them and inserted duplicate items.
Let us see the following output to check whether the sets are free of duplicate items:
Have a look at the preceding output carefully. While, as is the case with data classes, set ignored the duplicate items, when trying the same with a normal class, it was unable to detect the duplicate insertions and kept them.
Why is this an anomaly? The answer is short and simple—the collections framework internally uses hashCode() and equals() functions to perform equality checks while adding items to the set values and they are missing from the custom class.
So, if we implement those functions, then set will be able to distinguish between the duplicate items in the customClassSet values as well. Obviously, that's how it works for data classes as well. Just add the following code to the MyCustomClass definition and run the program to see the difference yourself:
override fun hashCode() = someStringValue.hashCode()+someNumericValue.hashCode() override fun equals(other: Any?): Boolean { return other is MyCustomClass && other.someNumericValue == someNumericValue && other.someStringValue==someStringValue }
Cool, isn't it? So, we are done with List and Set. Let us now have a look at the Map interface; then, we will discuss the data operation functions provided by the collections framework.