Ohjelmointi

Java Map.get ja Map.containKey

Kun käytetään Java's Map -toteutuksia, on joskus tavallista kutsua Karttan get (Object) -menetelmää ja reagoida eri tavalla sen perusteella, onko palautettu arvo nolla vai ei. Yleisesti voidaan olettaa, että Map.get (Object) -kohdasta palautettu nolla osoittaa, että kartalla ei ole syötettä annetulla avaimella, mutta näin ei ole aina. Todellakin, jos Java Kartta toteutus sallii nolla-arvot, niin se on mahdollista Kartta palauttaa arvon annetulle avaimelle, mutta arvo voi olla nolla. Usein tällä ei ole merkitystä, mutta jos sillä on väliä, voidaan käyttää Map.containsKey () -symbolia selvittääkseen, onko Kartta merkinnällä on avainmerkintä. Jos se tapahtuu ja Kartta palaa tyhjä get-puhelussa samalle avaimelle, on todennäköistä, että avain kartoittaa a tyhjä arvo. Toisin sanoen se Kartta saattaa palauttaa arvon "true" sisältääKey (Object) palaten samalla " tyhjä"varten saada (objekti). On joitakin Kartta toteutukset, jotka eivät salli tyhjä arvot. Tällöin a tyhjä "get" -puhelun tulee johdonmukaisesti vastata "false" -palautusta "sisältääKey" -menetelmästä.

Tässä blogikirjoituksessa esittelen näitä näkökohtia Map.get (objekti) ja Map.containsKey (Object). Ennen esittelyyn osallistumista huomautan ensin, että Map.getin (Object) Javadoc-dokumentaatio varoittaa nimenomaisesti hienovaraisista eroista Map.get (objekti) ja Map.containsKey (Object):

Jos tämä kartta sallii nolla-arvot, paluuarvo on tyhjä ei välttämättä tarkoita, että kartta ei sisällä avaimen kartoitusta; on myös mahdollista, että kartta kartoittaa nimenomaisesti avaimen tyhjä. sisältääKey toimintoa voidaan käyttää näiden kahden tapauksen erottamiseen.

Lähetyksen esimerkeissä käytän seuraavaksi määriteltyjä valtioiden luetteloita:

Valtiot. Java

pakkaus pölyä.esimerkkejä; / ** * Enum, joka edustaa tiettyjä läntisiä osavaltioita Yhdysvalloissa. * / julkisten valtioiden osavaltiot {ARIZONA ("Arizona"), KALIFORNIA ("Kalifornia"), COLORADO ("Colorado"), IDAHO ("Idaho"), KANSAS ("Kansas"), MONTANA ("Montana"), NEVADA ( "Nevada"), NEW_MEXICO ("New Mexico"), NORTH_DAKOTA ("Pohjois-Dakota"), OREGON ("Oregon"), SOUTH_DAKOTA ("Etelä-Dakota"), UTAH ("Utah"), WASHINGTON ("Washington"), WYOMING ("Wyoming"); / ** valtion nimi. * / yksityinen merkkijono stateName; / ** * Parametroitu enum-konstruktori, joka hyväksyy tilan nimen. * * @param newStateName Osavaltion nimi. * / States (lopullinen merkkijono newStateName) {this.stateName = newStateName; } / ** * Anna valtion nimi. * * @return valtion nimi * / public String getStateName () {return this.stateName; }} 

Seuraavassa koodiluettelossa käytetään yllä olevaa luetteloa ja täytetään valtioiden kartta pääkaupunkeihinsa. Menetelmä hyväksyy luokan, jonka tulisi olla Mapin erityinen toteutus, joka luodaan ja täytetään.

generateStatesMap (luokka)

/ ** * Luo ja täytä osavaltioiden kartta pääkaupungeille annetulla karttatyypillä. * Tämä menetelmä kirjaa myös kaikki Map-toteutukset, joiden nolla-arvot * eivät ole sallittuja. * * @param mapClass Luodun kartan tyyppi. * @return Valtioiden kartta pääkaupunkeihin. * / yksityinen staattinen kartta geneStatesMap (Luokan mapClass) {Kartan karttaToPopulate = null; if (Map.class.isAssignableFrom (mapClass)) {kokeile {mapToPopulate = mapClass! = EnumMap.class? (Kartta) mapClass.newInstance (): getEnumMap (); mapToPopulate.put (osavaltiot.ARIZONA, "Phoenix"); mapToPopulate.put (osavaltiotCALIFORNIA, "Sacramento"); mapToPopulate.put (osavaltiotCOLORADO, "Denver"); mapToPopulate.put (osavaltiotIDAHO, "Boise"); mapToPopulate.put (osavaltiot.NEVADA, "Carson City"); mapToPopulate.put (osavaltiot.NEW_MEXICO, "Sante Fe"); mapToPopulate.put (osavaltiot.NORTH_DAKOTA, "Bismark"); mapToPopulate.put (osavaltiot.OREGON, "Salem"); mapToPopulate.put (osavaltiot.SOUTH_DAKOTA, "Pierre"); mapToPopulate.put (osavaltiot.UTAH, "Salt Lake City"); mapToPopulate.put (osavaltiotWASHINGTON, "Olympia"); mapToPopulate.put (osavaltiot.WYOMING, "Cheyenne"); kokeile {mapToPopulate.put (osavaltiot.MONTANA, null); } catch (NullPointerException npe) {LOGGER.severe (mapToPopulate.getClass (). getCanonicalName () + "ei salli nolla-arvoja -" + npe.toString ()); }} catch (InstantiationException instantiationException) {LOGGER.log (Level.SEVERE, "Tyyppistä karttaa ei voida instantisoida" + mapClass.getName () + instantiationException.toString (), instantiationException); } catch (IllegalAccessExceptionegalAccessException) {LOGGER.log (Level.SEVERE, "Tyypin karttaa ei voi käyttää" + mapClass.getName () + laitonAccessException.toString (), laitonAccessException); }} else {LOGGER.warning ("Annettu tietotyyppi" + mapClass.getName () + "ei ole kartta."); } return mapToPopulate; } 

Yllä olevaa menetelmää voidaan käyttää erilaisten karttojen luomiseen. En näytä koodia juuri nyt, mutta esimerkkini luo nämä Mapsin neljällä erityisellä toteutuksella: HashMap, LinkedHashMap, ConcurrentHashMap ja EnumMap. Jokainen näistä neljästä toteutuksesta ajetaan sitten menetelmän läpi demonstrateGetAndContains (Kartta), joka näkyy seuraavaksi.

demonstrateGetAndContains (Kartta)

/ ** * Osoita Map.get (osavaltiot) ja Map.containsKey (osavaltiot). * * @param-kartta Kartta, jolla esittely tulisi suorittaa. * / private static void demonstrGetAndContains (lopullinen karttakartta) {final StringBuilder demoResults = new StringBuilder (); lopullinen merkkijono mapType = map.getClass (). getCanonicalName (); lopulliset valtiot montana = valtiot.MONTANA; demoResults.append (NEW_LINE); demoResults.append ("Tyyppikartta" + mapType + "palauttaa" + (map.get (montana)) + "Map.get (): lle" + montana.getStateName () "-toiminnolla; demoResults.append (NEW_LINE); demoResults.append ("Karttatyyppi" + mapType + "palauttaa" + (map.containsKey (montana)) + "Map.containsKey (): lle" + montana.getStateName () "-toiminnolla; demoResults.append (NEW_LINE); lopulliset valtiot kansas = osavaltiot.KANSAS; demoResults.append ("Tyyppikartta" + mapType + "palauttaa" + (map.get (kansas)) + "Map.get (): lle" + kansas.getStateName () "-toiminnolla; demoResults.append (NEW_LINE); demoResults.append ("Tyypin kartta" + mapType + "palauttaa" + (map.containsKey (kansas)) + "Map.containsKey (): lle" + kansas.getStateName () "-toiminnolla; demoResults.append (NEW_LINE); LOGGER.info (demoResults.toString ()); } 

Tätä mielenosoitusta varten perustin Mapsin tarkoituksella, että Montanan pääoma-arvot olisivat nolla, jotta Kansasiin ei olisi lainkaan merkintää. Tämä auttaa osoittamaan eroja Map.get (objekti) ja Map.containsKey (Object). Koska kaikki Map-toteutustyypit eivät salli nolla-arvoja, ympäröin sen osan, joka laittaa Montanan ilman isoa kirjainta try / catch-lohkoon.

Seuraavaksi näkyvät tulokset neljän tyyppisen Mapsin suorittamisesta koodin läpi.

17. elokuuta 2010 23:23:26 dustin.examples.MapContainsGet logMapInfo INFO: HashMap: {MONTANA = null, WASHINGTON = Olympia, ARIZONA = Phoenix, CALIFORNIA = Sacramento, WYOMING = Cheyenne, SOUTH_DAKAD_MAKER = Pierre, COLOR = Sante Fe, NORTH_DAKOTA = Bismark, NEVADA = Carson City, OREGON = Salem, UTAH = Salt Lake City, IDAHO = Boise} 17. elokuuta 2010 23:23:26 dustin.examples.MapContainsGet demonstrGetAndContains INFO: Map of type Java. util.HashMap palauttaa nollan Map.get (): lle käyttämällä Montana Map -tyyppiä java.util.HashMap palauttaa arvon true mallille Map.containsKey () käyttämällä Montana Map -tyyppiä java.util.HashMap palauttaa nollan Map.get (): lle Kansas Mapilla tyypin java.util.HashMap palauttaa epätosi Map.containsKey (): lle Kansasissa 17. elokuuta 2010 11:23:26 PM dustin.examples.MapContainsGet logMapInfo INFO: LinkedHashMap: {ARIZONA = Phoenix, CALIFORNIA = Sacramento, COLORADO = Denver, IDAHO = Boise, NEVADA = Carson City, NEW_MEXICO = Sante Fe, NORTH_DAKOTA = Bismark, OREGON = Salem, SOUTH_DAKOTA = Pierre, UTAH = Salt Lake City, WASHINGTON = Olympia, WYOMING = Cheyenne, MONTANA = null} 17. elokuuta 2010 23:23:26 dustin.examples.MapContainsGet demonstrGetAndContains INFO: Map of type java.util.LinkedHashMap return null for Map.get () using Montana Map of type java .util.LinkedHashMap palauttaa arvon tosi Map.containsKey (): lle käyttäen Montana Map -tyyppiä java.util.LinkedHashMap palauttaa nollan Map.get (): lle Kansas Map -tietokannan avulla java.util.LinkedHashMap palauttaa arvon false mapille Map.containsKey () Kansasilla 17. elokuuta 2010 23:23:26 dustin.examples.MapContainsGet generatesStatesMap SEVERE: java.util.concurrent.ConcurrentHashMap ei salli nolla-arvoja - java.lang.NullPointerException 17. elokuuta 2010 23:23:26 dustin.examples .MapContainsGet logMapInfo INFO: ConcurrentHashMap: {SOUTH_DAKOTA = Pierre, ARIZONA = Phoenix, WYOMING = Cheyenne, UTAH = Salt Lake City, OREGON = Salem, CALIFORNIA = Sacramento, IDAHO = Boise, NEW_MEXICO = NEW_MEXICO , WASHINGTON = Olympia, NEVADA = Carson City} 17. elokuuta 2010 23:23:26 dustin.examples.Ma pContainsGet demonstrGetAndContains INFO: Tyypin kartta java.util.concurrent.ConcurrentHashMap palauttaa nollan Map.get () -ominaisuudelle käyttämällä Montana Map -tyyppiä java.util.concurrent.ConcurrentHashMap palauttaa arvon false Map.containsKey (): lle käyttäen Montanan java.util-tyypin karttaa .concurrent.ConcurrentHashMap palauttaa nollapisteen Map.get (): lle Kansas Map -tietokannan avulla java.util.concurrent.ConcurrentHashMap palauttaa epätosi-arvon Map.containsKey (): lle Kansasin avulla 17. elokuuta 2010 11:23:26 PM dustin.examples.MapContainsGet logMapInfo INFO: EnumMap: {ARIZONA = Phoenix, CALIFORNIA = Sacramento, COLORADO = Denver, IDAHO = Boise, MONTANA = null, NEVADA = Carson City, NEW_MEXICO = Sante Fe, NORTH_DAKOTA = Bismark, OREGON = Salem, SOUTH_DAK Lake City, WASHINGTON = Olympia, WYOMING = Cheyenne} 17. elokuuta 2010 23:23:26 dustin.examples.MapContainsGet demonstrGetAndContains INFO: Kartan tyyppi java.util.EnumMap palauttaa nollan Map.get () -tyyppiselle Montanan tyypin kartalle. java.util.EnumMap palauttaa arvon Map.containsKey () tosi-arvon käyttämällä Montanan ty-karttaa pe java.util.EnumMap palauttaa nollapisteen Map.get (): lle Kansasissa käyttämällä tyypin java.util.EnumMap palauttaa arvon false, jos Map.containsKey () käyttää Kansasia 

Niille kolmelle karttatyypille, joille pystyin syöttämään nolla-arvoja, Map.get (Object) -kutsu palauttaa nollan, vaikka myöskomponentti (Object) palauttaisi "true" Montanalle, koska laitoin kyseisen avaimen karttaan ilman arvo. Kansasin osalta tulokset ovat johdonmukaisia ​​Map.get () palauttaa nollan ja Map.containsKey () palauttaa arvon "false", koska Kansasin kartoissa ei ole mitään merkintää.

Yllä oleva tuotos osoittaa myös, että en voinut asettaa Montanan pääomalle nolla-arvoa SamanaikainenHashMap toteutus (heitettiin NullPointerException).

17. elokuuta 2010 23:23:26 dustin.examples.MapContainsGet generoiStatesMapSEVERE: java.util.concurrent.ConcurrentHashMap ei salli nolla-arvoja - java.lang.NullPointerException

Tällä oli sivuvaikutus pitää Map.get (objekti) ja Map.containsKey (Object) johdonmukaisemmat vastaavat nolla- ja väärät palautusarvot. Toisin sanoen oli mahdotonta saada avain kartalle ilman vastaavaa ei-nolla-arvoa.

Monissa tapauksissa Map.get (objekti) toimii tarpeiden mukaan, mutta on parasta muistaa, että niiden välillä on eroja Map.get (objekti) ja Map.containsKey (Object) varmistaaksesi, että sopivaa käytetään aina. On myös mielenkiintoista huomata, että Map on samanlainen sisältääValue (Object) menetelmä.

Luettelon koko MapContainsGet-luokan koodiluettelon täydellisyyden vuoksi täältä:

MapContainsGet.java

$config[zx-auto] not found$config[zx-overlay] not found