Set and MutableSet

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.

Just like with list, set values also have read-only functions and properties like size, iterator(), and so on. We are skipping mentioning them here to avoid redundant contents in this book. Also, please note that set doesn't do ordering like list (unless you use OrderedSet). So, it lacks the functions which involve orders like indexOf(item), add(index, item), and so on.

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.

The last item that got added in dataClassSetMyDataClass(2,"will be added") if you think it was a duplicate item then check again, while the value of someNumericValue for this object is identical to a previous one, the someStringValue value differs from that previous object's someStringValue.

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.

In Kotlin, the compiler automatically extracts the hashCode() and equals() functions. Thus, the set values were able to distinguish between duplicate items without custom implementations of those functions. For more information on data classes visit the following link: https://kotlinlang.org/docs/reference/data-classes.html

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.124.177