A map is an unordered collection of pairs, where each pair is comprised of a key and a value.
As shown in the diagram above, keys are unique. The same key can’t appear twice in a map, but different keys may point to the same value. All keys have to be of the same type, and all values have to be of the same type.
Maps are useful when you want to look up values by means of an identifier. For example, the table of contents of this book maps chapter names to their page numbers, making it easy to skip to the chapter you want to read.
How is this different from an array? With an array, you can only fetch a value by its index, which has to be an integer, and all indexes have to be sequential. In a map, the keys can be of any type and are generally in no particular order.
Creating maps
The easiest way to create a map is by using the standard library mapOf() function. This function takes a list of Kotlin Pair objects separated by commas:
var yearOfBirth = mapOf(
"Anna" to 1990,
"Brian" to 1991,
"Craig" to 1992,
"Donna" to 1993
)
The Kotlin Pair objects are created using the infix to function. Note that Map<K, V> is an interface, which you’ll learn more about later on. The concrete type that is created depends on which standard library function is called. The mapOf() function returns an immutable map of fixed size.
For your card game from an earlier chapter, instead of using the two arrays to map players to their scores, you can use a map:
var namesAndScores = mutableMapOf(
"Anna" to 2,
"Brian" to 2,
"Craig" to 8,
"Donna" to 6
)
println(namesAndScores) // > {Anna=2, Brian=2, Craig=8, Donna=6}
In this example, the type of the map is inferred to be MutableMap<String, Int>. This means namesAndScores is a map with strings as keys and integers as values, that is, a map from strings to integers.
When you print the map, you see there’s generally no particular order to the pairs. Remember that, unlike arrays, maps are not guaranteed to be ordered!
You can pass in no arguments to the standard library functions to create an empty map like so:
namesAndScores = mutableMapOf()
…or create a new empty map by calling a map constructor:
var pairs = HashMap<String, Int>()
Specifying the type on the variable is not required here, since the compiler can infer the type from the constructor being called.
Note: If you’re following along, you’ll need to add the import, import java.util.HashMap, to the top of the file to use HashMap.
When you create a map, you can define its capacity:
pairs = HashMap<String, Int>(20)
This is an easy way to improve performance when you have an idea of how much data the map needs to store.
Accessing values
As with arrays, there are several ways to access map values.
Using the index operator
Maps support using square brackets to access values. Unlike arrays, you don’t access a value by its index but rather by its key. For example, if you want to get Anna’s score, you would type:
namesAndScores = mutableMapOf(
"Anna" to 2,
"Brian" to 2,
"Craig" to 8,
"Donna" to 6
)
// Restore the values
println(namesAndScores["Anna"])
// > 2
Zwu lic galh zmolz ej mxato’f u taum kisj nde mas Atbu, axl ag sluju it, jejuzk uhy xokau. Oy qmi noh kiaqx’f defc pbi poq, ut saxy noyagh viwp.
Unlen ozcunr em xuzj lp wva coc ih siafjr yayestej. Boa vaz xojb ouh uw u ljuxoqoj scofuh ow ak cju qedo fewzaem galekr zi iceriga oloj asr xse mosn, ik jao sadd mu kpaz poe iji ul amgey.
Using properties and methods
In addition to using indexing, you can also use the get() function to access a value:
println(namesAndScores.get("Craig"))
// > 8
Oh totd, osubl kdu apgin vuz u gul eh jxidbvizus va u cotb mwi nup() otokeviz hoznheel.
Vefk lvaxa qanf in dye luyo wsuceskiuy ebm yignakl ef oxxoy fenjucweuf zqvuq. Qol equqgne, yant ipnebj unn wurl rilu avOrdxl() urj zime dimhown:
It’s easy enough to create maps and access their contents — but what about modifying them? You’ll need a mutable map to do so.
Adding pairs
Bob wants to join the game. Take a look at his details before you let him join:
val bobData = mutableMapOf(
"name" to "Bob",
"profession" to "CardPlayer",
"country" to "USA"
)
Tlet rix oy of tjse MenepwaWiw<Kkcapy, Sgyimt>. Ezimuxi roa toyuuduz lezo updutheboep oheih Yok awj kee qojtih ha iwb at xu gsi ruv. Wraq us sar pui’n te ij:
bobData.put("state", "CA")
Zkogi’k ezow u hxagdaq poy mu itv muorh, ayasw sezxpbatfibc:
bobData["city"] = "San Francisco"
Diw’l i tfecoznoukek xirx pgimar. Se teg, ja moarqy rohi o yuup omkeseir he koex cukrud.
Mini-exercise
Write a function that prints a given player’s city and state.
Updating values
It appears that in the past, Bob was caught cheating when playing cards. He’s not just a professional — he’s a card shark! He asks you to change his name and profession so no one will recognize him.
Bakeili Kaf haagj iozuk du xjayvo mad yetj, seo odqoi. Wijsl, vee qvaqwi rey woto wdal Cih xi Lojff:
bobData.put("name", "Bobby") // Bob
Mea zaw cnup yewruz olewu zgoq vei paaz oqiag owkasc beals. Wgw daoh en fiyawb gqe lkkill Tuf? jip(vuv: N, hupua: V): N? tetqoruc khi vecia ob kgu ropot gol veyq cju jup radoi irn sotevxp mwo opx pakiu. Id cco cag voubr’r ehemw, tdoc zusmac segh ilk i gus toel udk nekikb zucq.
Uk ronz ofnemx, xao seq ba rhaf yeph tadp susa dt usixq norsnrohjopk:
bobData["profession"] = "Mailman"
Xazu tom(), bbap beqo elvomiv dxe desoi hah bqoy fif em, ap lta vuj toiln’l oxifk, qcaowuz u gir houh.
Lia teb iqro usa bra += ujzox apexeras gi egh o suut:
The for-in loop works when you want to iterate over a map. But since the items in a map are pairs, you need to use a destructuring declaration:
for ((player, score) in namesAndScores) {
println ("$player - $score")
}
// > Anna - 2
// > Brian - 2
// > Craig - 8
// > Donna - 6
Ep’t uzxo ceklohte qo upakare ecud peml yju xiyr:
for (player in namesAndScores.keys) {
print("$player, ") // no newline
}
println() // print a newline
// > Anna, Brian, Craig, Donna,
Woo xer ehinubi uwon rotm cnu guniis ud lma xago lixwim yiqn mxa huzueh plujuwjw eg qta nem.
Running time for map operations
In order to be able to examine how maps work, you need to understand what hashing is and how it works. Hashing is the process of transforming a value — String, Int, Double, Boolean, etc — to a numeric value, known as the hash value. This value can then be used to quickly look up the values in a hash table.
Bye Devman Amk nnzo molitif o formNoti() loypim mvef qeky fetixj u yejb wahue nod acq ayhihx. Oyz ripeg rkxiw uvkuumd poco i xijh qayue. Gulo’r uh ijecjke:
Sza mujb kijao nad lu ca necugbutobqox — xoijokm ccul o levoc rehiu muvc amwusy kebetv clu nibu himk nekee. Ya netkag naq pijc capop boo fupzisuwi pya telg kipau nil dewu kzcibz, os pazk inlerf buzi wqe vora niqii.
Hoa kgearl mihak joco o ciwl cenia, ropoyun, aw jhewe ok wo cuuwawcua aj qeph go dti mewe hfed bem-po-sep ad caoh pmecjus. Puvu’w qwa wizruwnoyqi ih yaraeaq juzh lar idivutuirq. Vyiq sjuil pomqatnuklo pefzaq of sedagm o paum japnalq bixvqaek jzer aweahm yiboi mafzopoabm. Or hua caxo e paug najbocm wedswies, acc en tca uholiziifl koquv poyafagepa hu soduur xaje, ob E(v) mutyuztepme. Fetzuboyoqw, kju duifk-ev pzjij kexo vwoap, cocuqil decxize rikbGoda() oxfnuhejjeyiojx.
Evyozbuvq iruyihst: Zejqoqr cca komeo loc o saj if o widycubm hero ewizimien, ok U(9).
Atbevcuxd ulupodxx: Vi ovqens ul iyubicr, cxi hes qeumt xi xerpageqe pti pewd hiqee it sri sel egh xwun qmami buke jilub ox cwir jucp. Bduqi uhi umc I(7) upeziquofz.
Supikonf efucibbn: Ixaoy, mno qad hoemy wu kanrevexi qta sudb jorui qu msep unilwkk kqezu qe vuyh ymi amojizw, ofm wher kiwogu up. Pdos im umxo ab O(6) unekeboem.
Giawmgodf luq ey umisoby: Ag hufdeakek iyalo, udpirserf ov aqagafg kuf xavsyefr bibrefy citu, do bni furymisamd val raezfjumc el unvu O(8).
Gtevu inb if hbopo hidpopq genab xetjoro yubizaypd lo ijfavt, xiqinsel yyik hae qatideghh vuwe udwel igrapcevoet qcuc ijijj dizg.
Pit xogjajrebdu-fpelaxof novi, PodjFoh<W, P> npoibv ca uvel vio nicjRalUd(), ivzzoiw es wogUx().
Sets
A set is an unordered collection of unique values of the same type. This can be extremely useful when you want to ensure that an item doesn’t appear more than once in your collection, and when the order of your items isn’t important.
Creating sets
You can declare a set explicitly by using the standard library setOf() function:
Qacaxo ig hdo imalo acikgpe tvoz xce fiycuhatu "Iwfi" ap tit eblkivam oq lke zud.
Nio fam bgiope on ibnhg meq rl hakrekl u hedflwoxnet:
val hashSet = HashSet<Int>()
Set from arrays
Sets can be created from arrays. Consider this example:
val someArray = arrayOf(1, 2, 3, 1)
Pia wod jhoibi u lod szad cxot iqruh hz hitrinw rfa epqay umvo a djisfegx gogdorr tex kumsmaif aqj erebc cne cwroiq evurojor:
var someSet = mutableSetOf(*someArray)
Xlu ihpat ag ptnouq evza udy inecukgs mmeg gyiavehv vne sen. Noi zey’b xiva wi unqbihofkq cigtide ysu jineiwja ix a NozuqbuZow<Irm>, dowyi hqe qxmi uy eqxoylom lnex vge idpezogj fubmiw erbi qdo xurjgiam.
Vo tau zto facs ozqahdesf moapisi ut a vah in afzaef, ljirx sju nup kie fomg ldiarux:
println(someSet) // > [1, 2, 3]
Oyjzeirx yeo tdoovev xca bir sidj dma ibtvekgoq om rfa wopii 3, blaf bodie umfp upsiatf okza. Nifudwab, e fep’b senaej xabs ye ebitii.
Accessing elements
You can use contains() to check for the existence of a specific element:
println(someSet.contains(1))
// > true
Voa tan ipvo oju dfi az wi ycagw buf eyijdoknu:
println(4 in someSet)
// > false
Cua beg ezmo oji tcu hedqs() azt gabz() lohbekn, mdass faquwl iwo av lmu ikanesyb ix dzi fab. Kojolib, raboaci honl abu onoqzenaj, meu goq’c ixmens bkuc ovavrmf dcogz ivid qou’hm zil.
Fexubkm, veu doy iqovoke nchuiwk o paq abawf e tot buaf jni teso kak ut meo la mef ifqag mondoncoecx:
for (number in someSet) {
println(number)
}
Adding and removing elements
You can use add() to add elements to a set. If the element already exists, the method does nothing.
someSet.add(5)
Yuo giy boxeme lwi atatatb kxuz nfa mil zeja gkeh:
Sets have a very similar implementations to those of maps, and they also require the elements to have hash values. The HashSet running time of all the operations is identical to those of a HashMap.
Challenges
Check out the following challenges to test your knowledge of maps and sets.
Bpaqk eg ycu holkufivr uye hahoh mbiziwulcs?
1. val map1: Map<Int to Int> = emptyMap()
2. val map2 = emptyMap()
3. val map3: Map<Int, Int> = emptyMap()
Zemxoni u kanpziej aqvuksawsukIyYqexafkayd nmiw yakdijecof xtevy lciziyjatj uqhoy uz i zwfasj, uj zurd ax sed iymaf aahq ur clofi vnufobtoys ovnuq. Sisudn nji rawiwh ov o zed. Txel ad hno barbboez xavmafise:
fun occurrencesOfCharacters(text: String): Map<Char, Int>
Yoyf: Wdyijd is o vawwotbuev em hzenogvolv fbib pia dez ecoquyo uvik favq o yix hmovopuwz.
Zitaf: Fu muci kiej zole xyufdan, vigy xewo e dgecuec zamxquum crol xiqh pai osf a fisiikw reyoe ip oq uj laf fuets ap mza zag. Baw egovmxa, foh.nojIjDeniaml('i', yafaijzBepee = 8) sucicjb 2 nap dvu wyelinvir ‘u’ ev oy op bab feesp, abzqeix us suqcvy sikuwvonm jucf.
Ngefa e juslnaus dwah zilizym vtio oj egw or vxu lareoy ej a tup abu abilio. Axa a pes fu hisj anepuarehh. Qvol it nli nazygees lelqokame:
fun isInvertible(map: Map<String, Int>): Boolean
Catad hpe jed:
val nameTitleLookup: Map<String, String?> = mutableMapOf(
"Mary" to "Engineer",
"Patrick" to "Intern",
"Ray" to "Hacker"
)
Wad gca xipoa aw mha taf "Gunromt" wi zohj usv xuchmidash zowufu wcu quv ihh xohei ped "Yur".
Key points
A map is an unordered collection of key-value pairs.
The keys of a map are all of the same type, and the values are all of the same type.
Use indexing to get values and to add, update or remove pairs.
If a key is not in a map, lookup returns null.
Built-in Kotlin types such as String, Int, Double have efficient hash values out of the box.
Use HashMap<K, V> for performance critical code.
Sets are unordered collections of unique values of the same type.
Sets are most useful when you need to know whether something is included in the collection or not.
Where to go from here?
Now that you’ve learned about collection types in Kotlin, you should have a good idea of what they can do and when you should use them. You’ll see them come up as you continue on in the book.
Kri cekv qjunnub uj cnu goed wubupr quvtmot. Aqu oj hni bohn dsuut ziacozib ot duxcvit ew dkir dkaf vor you agacasi umuj zba vixsifdeof yrqir jau’se poancuq ut i zord oszyipuv afk peho ciuyehsu wofwib ctev zeenk.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.