Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between setOf and hashSetOf in Kotlin

Tags:

kotlin

What the difference between setOfStrings and hashSetOfStrings produced by following code snippet?

val setOfStrings = setOf("A", "B", "C")
val hashSetOfStrings = hashSetOf("A", "B", "C") 

Do they always have the same type? The same performance?

like image 350
yanefedor Avatar asked Dec 23 '22 19:12

yanefedor


2 Answers

The most important difference between them is mutability.

setOf() returns an object which implements the Set interface, but is probably immutable (not implementing the MutableSet subinterface), and so can't be changed.

(The online docs specify that it's read-only, which doesn't necessarily mean immutable.  But it's safest to assume so.)

It doesn't specify the concrete type; this is probably to allow it to be changed in future to improve performance, memory usage, and/or similar.  Even now, it could return a kotlin.collections.EmptySet, java.util.Collections.SingletonSet, or a kotlin.collections.LinkedHashSet; the latter has faster (and predictable) iteration compared to a standard HashSet.

So setOf() is for when you want an efficient, immutable set and don't care about the exact type.

hashSetOf(), on the other hand, always returns a kotlin.collections.HashSet (or a subclass), which is always mutable.  That's for when you need that particular type.

And if you want a mutable set but don't care about the exact type, you're best off calling mutableSetOf().

(In general, of course, it's best not to specify concrete types when you don't really need to; that keeps your code flexible.)

like image 137
gidds Avatar answered Feb 01 '23 16:02

gidds


There are a few differences.

First, and most importantly, with setOf you are telling Kotlin - "I want a set, you go figure out what kind, I don't have a preference". But with hashSetOf you are telling Kotlin that you want a HashSet specifically.

Second, setOf will create a read-only set, whereas hashSetOf will create a HashSet, which implements MutableSet, allowing writes. (Under the covers, ultimately setOf gives you a LinkedHashSet typed as a Set so it is read-only) .

As for setOfStrings, it is type Set<String> (read-only, backed by LinkedHashSet) whereas hashSetOfStrings is HashSet<String> (read/write, backed by HashSet).

Adding the types in might make this more clear:

val setOfStrings: Set<String> = setOf("A", "B", "C")
val hashSetOfStrings: HashSet<String> = hashSetOf("A", "B", "C")
like image 38
Todd Avatar answered Feb 01 '23 16:02

Todd