Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Mikä on Map? | Osio
Javan Perustietorakenteet

Mikä on Map?

Pyyhkäise näyttääksesi valikon

Tarkastelemme Map-rajapintaa Javassa. Map-rajapinta kuuluu Java Collections -kehykseen ja määrittelee menetelmät tietojen käsittelyyn avain-arvo-pareina.

Tarkastellaan määritelmää:

Tämän tietorakenteen ensisijainen toteutus Javassa on HashMap, joka toteuttaa Map-rajapinnan. Tutustutaan tämän toteutuksen päämenetelmiin ja toimintaperiaatteisiin.

Aloitetaan määrittelystä ja menetelmistä:

Main.java

Main.java

1
Map<K, V> map = new HashMap<>();

Tässä näet, että geneerisissä tai timanttisulkeissa määritellään kaksi arvoa:

  • Arvo K vastaa avaimen tietotyyppiä;
  • Arvo V vastaa arvon tietotyyppiä.

Kun siis määrittelemme tämän tietorakenteen, ilmoitamme avain-arvo-parien tietotyypit.

Seuraavaksi tarkastellaan Map-rajapinnassa määriteltyjä metodeja.

Metodit

V put(K key, V value): liittää annetun arvon annettuun avaimeen tässä Map:ssa. Jos Map sisälsi aiemmin avaimelle liitoksen, vanha arvo korvataan.

Main.java

Main.java

1234567891011121314
package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println(map); } }

V get(Object key): palauttaa arvon, johon määritetty avain on liitetty, tai null, jos tässä Map-rakenteessa ei ole avainta vastaavaa arvoa.

Tässä määritetään avain, jolla haetaan vastaava arvo.

Haetaan arvo, jonka avain on 2:

Main.java

Main.java

12345678910111213141516
package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); String value = map.get(2); System.out.println("Value: " + value); } }
  • boolean containsKey(Object key): palauttaa true, jos Map sisältää määritetyn avaimen;

  • boolean containsValue(Object value): palauttaa true, jos Map sisältää yhden tai useamman avaimen, joka on liitetty määritettyyn arvoon.

Nämä kaksi metodia ovat selvästi yhteydessä toisiinsa, ja niiden avulla voidaan selvittää, sisältääkö Map halutut avaimet tai arvot. Näitä metodeja on kätevää käyttää ehtolauseissa, koska ne palauttavat boolean-arvon.

Tarkastellaan esimerkkiä:

Main.java

Main.java

12345678910111213141516171819202122232425
package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); if (map.containsKey(2)) { System.out.println("Value with key 2: " + map.get(2)); } else { System.out.println("There is no value with key 2!"); } if (map.containsValue("Four")) { System.out.println(map.get(4)); } else { System.out.println("There is no key with value \"Four\"!"); } } }

Yllä olevassa esimerkissä tarkistetaan avaimen olemassaolo ja arvon olemassaolo Map-rakenteessa. Jos arvot löytyvät, ne näytetään konsolissa. Jos arvoja ei löydy, tulostetaan viestit, jotka ilmaisevat tietojen puuttumisen.

  • boolean isEmpty(): palauttaa true, jos tämä Map ei sisällä avain-arvo-pareja;

  • V remove(Object key): poistaa määritetyn avaimen mukaisen parin tästä Map-rakenteesta, jos se on olemassa, ja palauttaa aiemman arvon.

Kuten muissakin tietorakenteissa, voit poistaa alkioita Map-rakenteesta.

Main.java

Main.java

12345678910111213141516
package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); String removedElement = map.remove(3); System.out.println("Removed value: " + removedElement + ".\nMap after the removal operation: " + map); } }

Näin ollen voimme poistaa alkioita avaimen perusteella.

Perusmenetelmät Mapin hallintaan

Seuraavaksi on menetelmiä, jotka ovat jo entuudestaan tuttuja, ja luettelen ne ilman esimerkkejä. Mutta jäljellä on myös mielenkiintoisia menetelmiä.

Aloitetaan perusteista:

  • void clear(): poistaa kaikki alkiot Map-rakenteesta;

  • int size(): palauttaa avain-arvo-parien lukumäärän tässä Map-rakenteessa;

  • void putAll(Map<? extends K, ? extends V> m): kopioi kaikki annetun Map-rakenteen avain-arvo-parit tähän Map-rakenteeseen.

Seuraavaksi tarkastellaan menetelmiä, jotka palauttavat kokoelman arvoista (tai avaimista) Map-rakenteesta. Toisin sanoen haemme tietorakenteesta avain-arvo-rakenteen, joka sisältää vain arvot (tai avaimet). Esimerkiksi ArrayList<>.

Main.java

Main.java

12345678910111213141516
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); Collection<String> list; list = map.values(); System.out.println("Values" + list); } }

Tässä saatiin kokoelma arvoja Map-rakenteesta. Nyt voimme siirtää tämän kokoelman ArrayList-rakenteeseen:

Main.java

Main.java

123456789101112131415161718
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); Collection<String> collection; collection = map.values(); System.out.println("Values" + collection); List<String> arrayList = new ArrayList<>(collection); System.out.println("ArrayList: " + arrayList); } }

Alustimme ArrayList-rakenteen käyttäen arvoja Map-rakenteesta.

Map-rakenteesta on myös menetelmä, joka palauttaa avaimet. Nämä avaimet palautetaan kuitenkin rakenteessa nimeltä Set. Emme käsittele tätä tietorakennetta tarkemmin tässä vaiheessa; on kuitenkin hyvä mainita, että Set on tietorakenne, joka sisältää ainoastaan yksilöllisiä arvoja.

Tarkastellaan tätä menetelmää:

Set<K> keySet(): palauttaa Set-näkymän tämän Map-rakenteen sisältämistä avaimista.

Main.java

Main.java

12345678910111213141516
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); Set<Integer> keys; keys = map.keySet(); System.out.println("Keys: " + keys); } }

Näin ollen voimme myös hakea joukon kaikkia avaimia Map-rakenteesta.

Vaikuttaa siltä, että olemme käsitelleet kaikki metodit. Tarkastellaan nyt Map-rakenteen käyttöä sekä käytännön esimerkkejä:

Mapin käyttö

Avain-arvo -rakenne soveltuu moniin käytännön tarkoituksiin. Tarkastellaan yksinkertaisinta näistä rakenteista: opiskelijoiden arvostelujärjestelmää.

Luodaan Map, jossa avain on tyyppiä String ja edustaa opiskelijan nimeä, ja arvo on tyyppiä Integer ja edustaa opiskelijan arvosanaa. Näin voit liittää arvosanat opiskelijoihin ja hakea helposti tietyn opiskelijan arvosanan avaimen avulla:

Main.java

Main.java

12345678910111213141516
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> studentsGrades = new HashMap<>(); studentsGrades.put("Bob", 9); studentsGrades.put("Alice", 8); studentsGrades.put("Mike", 5); studentsGrades.put("John", 10); studentsGrades.put("Martin", 7); studentsGrades.put("Peter", 5); System.out.println("Student's grades: " + studentsGrades); } }

Kuvitellaan nyt, että tehtävänä on hakea Miken ja Alicen arvosanat ja vertailla niitä keskenään. Tämä onnistuu helposti yllä opituilla menetelmillä. Toteutetaan tämä koodissa:

Main.java

Main.java

123456789101112131415161718192021
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> studentsGrades = new HashMap<>(); studentsGrades.put("Bob", 9); studentsGrades.put("Alice", 8); studentsGrades.put("Mike", 5); studentsGrades.put("John", 10); studentsGrades.put("Martin", 7); studentsGrades.put("Peter", 5); System.out.println("Student's grades: " + studentsGrades); Integer mikeGrade = studentsGrades.get("Mike"); Integer aliceGrade = studentsGrades.get("Alice"); System.out.println(mikeGrade.compareTo(aliceGrade) == -1 ? "Alice's grade is higher": "Mike's grade is higher"); } }

Käytettiin ternääristä operaattoria sekä compareTo()-kääreluokan Integer-metodia. Jos et ymmärrä, miten tämä toimii, se voidaan selittää seuraavasti:

Main.java

Main.java

12345678910111213141516171819202122232425
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> studentsGrades = new HashMap<>(); studentsGrades.put("Bob", 9); studentsGrades.put("Alice", 8); studentsGrades.put("Mike", 5); studentsGrades.put("John", 10); studentsGrades.put("Martin", 7); studentsGrades.put("Peter", 5); System.out.println("Student's grades: " + studentsGrades); Integer mikeGrade = studentsGrades.get("Mike"); Integer aliceGrade = studentsGrades.get("Alice"); if (mikeGrade.compareTo(aliceGrade) == -1) { System.out.println("Alice's grade is higher"); } else { System.out.println("Mike's grade is higher"); } } }

Tarkastellaanpa nyt, mitä tapahtuu, jos meitä pyydetään keräämään kaikki opiskelijat, joiden arvosana on yli 7 (pois lukien 7). Tämä tekee tehtävästä mielenkiintoisen, ja selitän nyt, kuinka se tehdään!

Iterointi Mapin läpi

Elementtien läpikäynti Map-rakenteessa Javassa voidaan toteuttaa useilla tavoilla, jotka Map-rajapinta ja sen toteutukset tarjoavat. Tässä on useita tapoja iteroida Map-rakenteen läpi:

Iterointi avainten yli (keySet()): keySet()-metodi palauttaa joukon kaikkia Mapin avaimia. Tätä joukkoa voidaan käyttää avainten läpikäyntiin ja vastaavien arvojen hakemiseen.

Main.java

Main.java

12345678910111213141516
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("Key1", 1); map.put("Key2", 2); for (String key : map.keySet()) { Integer value = map.get(key); System.out.println("Key: " + key + ", Value: " + value); } } }

Arvojen läpikäynti (values()): values()-metodi palauttaa kokoelman kaikista Map-olion arvoista. Tätä kokoelmaa voidaan käyttää arvojen läpikäyntiin.

Main.java

Main.java

123456789101112131415
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("Key1", 1); map.put("Key2", 2); for (Integer value : map.values()) { System.out.println("Value: " + value); } } }

Avainten ja arvojen läpikäynti (entrySet()): entrySet()-metodi palauttaa joukon Map.Entry -olioita, jotka edustavat avain-arvo-pareja. Tämä mahdollistaa parien läpikäynnin suoraan.

Main.java

Main.java

1234567891011121314151617
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("Key1", 1); map.put("Key2", 2); for (Map.Entry<String, Integer> entry : map.entrySet()) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println("Key: " + key + ", Value: " + value); } } }

Tarkastellaan tätä hieman tarkemmin. Aluksi tämä saattaa vaikuttaa erittäin monimutkaiselta ymmärtää, mutta sinun ei tarvitse perehtyä yksityiskohtiin, sillä syntaksi on aina sama.

Map.Entry<K, V> entry : map.entrySet()

entry-olion avulla voit samanaikaisesti tarkastella sekä avainta että arvoa Map:issa. Nyt ratkaistaan aiemmin annettu tehtävä käyttämällä entry setiä: haetaan kaikki opiskelijat, joiden arvosana on yli 7. Tätä varten käytetään tarkistusta entry.getValue()-kutsulla, ja kun sopiva opiskelija löytyy, tallennetaan hänen avaimensa ennalta luotuun ArrayList:iin:

Main.java

Main.java

1234567891011121314151617181920212223242526
package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> studentsGrades = new HashMap<>(); studentsGrades.put("Bob", 9); studentsGrades.put("Alice", 8); studentsGrades.put("Mike", 5); studentsGrades.put("John", 10); studentsGrades.put("Martin", 7); studentsGrades.put("Peter", 5); System.out.println("Student's grades: " + studentsGrades); List<String> studentsWithGradeHigherThanSeven = new ArrayList<>(); for (Map.Entry<String, Integer> entry : studentsGrades.entrySet()) { if (entry.getValue() > 7) { studentsWithGradeHigherThanSeven.add(entry.getKey()); } } System.out.println(studentsWithGradeHigherThanSeven); } }

Näin voit käydä läpi Map-rakennetta ja löytää halutun listan opiskelijoista, jotka läpäisivät kokeen!

Entry set on erittäin hyödyllinen työkalu, sillä se mahdollistaa useita tapoja iteraation suorittamiseen Map-rakenteessa silmukan avulla, jolloin sekä avain että arvo ovat käytettävissä.

Seuraavassa luvussa perehdymme tarkemmin siihen, miten HashMap, jota käytimme tässä luvussa aktiivisesti, todellisuudessa toimii!

1. Mikä rajapinta Javassa edustaa avain-arvo -parien kokoelmaa?

2. Kuinka iteroidaan kaikki avaimet Map-rakenteessa for-each-silmukalla?

3. Mikä on values()-metodin tarkoitus Map-rakenteessa?

4. Millä metodilla tarkistetaan, onko tietty avain olemassa Map-rakenteessa?

5. Mitä menetelmää käytetään avain-arvoparin poistamiseen Map-rakenteesta Javassa?

question mark

Mikä rajapinta Javassa edustaa avain-arvo -parien kokoelmaa?

Valitse oikea vastaus

question mark

Kuinka iteroidaan kaikki avaimet Map-rakenteessa for-each-silmukalla?

Valitse oikea vastaus

question mark

Mikä on values()-metodin tarkoitus Map-rakenteessa?

Valitse oikea vastaus

question mark

Millä metodilla tarkistetaan, onko tietty avain olemassa Map-rakenteessa?

Valitse oikea vastaus

question mark

Mitä menetelmää käytetään avain-arvoparin poistamiseen Map-rakenteesta Javassa?

Valitse oikea vastaus

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 1. Luku 13

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

Osio 1. Luku 13
some-alt