Programovanie

Java Map.get a Map.containsKey

Pri použití implementácií Java Map je niekedy bežné vyvolať Mapa's (Object) a reagovať rôzne na základe toho, či je vrátená hodnota nulová alebo nie. Možno predpokladať, že hodnota null vrátená z nástroja Map.get (Object) naznačuje, že na mape nie je žiadny záznam s poskytnutým kľúčom, ale nie je to tak vždy. Skutočne, ak je Java Mapa implementácia umožňuje nulové hodnoty, potom je možné pre Mapa vrátiť jeho hodnotu pre daný kľúč, ale táto hodnota môže mať nulovú hodnotu. Často to nevadí, ale ak áno, môžete pomocou Map.containsKey () zistiť, či Mapa záznam má kľúčový záznam. Ak áno a Mapa vracia nulový pri volaní toho istého kľúča je pravdepodobné, že sa tento kľúč mapuje na a nulový hodnotu. Inými slovami, to Mapa by sa mohlo vrátiť „pravdivé“ pre containsKey (Object) a zároveň sa vracia “ nulový„pre get (Object). Niektoré sú Mapa implementácie, ktoré neumožňujú nulový hodnoty. V týchto prípadoch a nulový z volania „get“ by sa malo zhodovať s „false“ návratom z metódy „containsKey“.

V tomto blogovom príspevku demonštrujem tieto aspekty Map.get (objekt) a Map.containsKey (objekt). Predtým, ako sa pustím do tejto demonštrácie, najskôr upozorním, že dokumentácia Javadoc pre Map.get (Object) výslovne varuje pred jemnými rozdielmi medzi Map.get (objekt) a Map.containsKey (objekt):

Ak táto mapa umožňuje nulové hodnoty, potom návratová hodnota je nulový nemusí nutne znamenať, že mapa neobsahuje žiadne mapovanie kľúča; je tiež možné, že mapa výslovne mapuje kľúč k nulový. The containsKey operáciu možno použiť na rozlíšenie týchto dvoch prípadov.

Pre príklady príspevku použijem enum definovaný ďalej:

States.java

balenie zásypu.príklady; / ** * Enum zastupujúci vybrané západné štáty v Spojených štátoch. * / public enum Štáty {ARIZONA („Arizona“), CALIFORNIA („Kalifornia“), COLORADO („Colorado“), IDAHO („Idaho“), KANSAS („Kansas“), MONTANA („Montana“), NEVADA ( „Nevada“), NEW_MEXICO („Nové Mexiko“), NORTH_DAKOTA („Severná Dakota“), OREGON („Oregon“), SOUTH_DAKOTA („Južná Dakota“), UTAH („Utah“), WASHINGTON („Washington“), WYOMING („Wyoming“); / ** Názov štátu. * / private String stateName; / ** * Parametrizovaný konštruktor enum, ktorý prijíma názov stavu. * * @param newStateName Názov štátu. * / States (konečný reťazec newStateName) {this.stateName = newStateName; } / ** * Uveďte názov štátu. * * @return Názov štátu * / public String getStateName () {return this.stateName; }} 

Nasledujúci zoznam kódov používa vyššie uvedený výčet a vyplní mapu štátov do ich hlavných miest. Metóda prijíma triedu, ktorá by mala byť konkrétnou implementáciou Mapy, ktorá sa má generovať a naplniť.

generateStatesMap (trieda)

/ ** * Vytvorte a vyplňte Mapu štátov na veľké písmená poskytnutým typom Mapy. * Táto metóda tiež zaznamenáva všetky implementácie mapy, pre ktoré nie sú povolené nulové hodnoty. * * @param mapClass Typ mapy, ktorá sa má vygenerovať. * @return Mapa štátov do hlavných miest. * / private static Map generateStatesMap (Class mapClass) {Map mapToPopulate = null; if (Map.class.isAssignableFrom (mapClass)) {try {mapToPopulate = mapClass! = EnumMap.class? (Mapa) mapClass.newInstance (): getEnumMap (); mapToPopulate.put (States.ARIZONA, "Phoenix"); mapToPopulate.put (States.CALIFORNIA, "Sacramento"); mapToPopulate.put (States.COLORADO, "Denver"); mapToPopulate.put (States.IDAHO, "Boise"); mapToPopulate.put (States.NEVADA, "Carson City"); mapToPopulate.put (States.NEW_MEXICO, "Sante Fe"); mapToPopulate.put (States.NORTH_DAKOTA, "Bismark"); mapToPopulate.put (States.OREGON, "Salem"); mapToPopulate.put (States.SOUTH_DAKOTA, "Pierre"); mapToPopulate.put (States.UTAH, "Salt Lake City"); mapToPopulate.put (States.WASHINGTON, "Olympia"); mapToPopulate.put (States.WYOMING, "Čejen"); try {mapToPopulate.put (States.MONTANA, null); } catch (NullPointerException npe) {LOGGER.severe (mapToPopulate.getClass (). getCanonicalName () + "neumožňuje nulové hodnoty -" + npe.toString ()); }} catch (InstantiationException instantiationException) {LOGGER.log (Level.SEVERE, "Nemôžem vytvoriť inštanciu Mapy typu" + mapClass.getName () + instantiationException.toString (), instantiationException); } catch (IllegalAccessException legalAccessException) {LOGGER.log (Level.SEVERE, "Nemôžem získať prístup k Mape typu" + mapClass.getName () + legalAccessException.toString (), nelegálny prístup) }} else {LOGGER.warning ("Poskytovaný dátový typ" + mapClass.getName () + "nie je Mapa."); } vrátiť mapToPopulate; } 

Vyššie uvedenú metódu je možné použiť na generovanie máp rôznych druhov. Momentálne nezobrazujem kód, ale môj príklad vytvára tieto Mapy so štyrmi konkrétnymi implementáciami: HashMap, LinkedHashMap, ConcurrentHashMap a EnumMap. Každá z týchto štyroch implementácií sa potom vykonáva touto metódou demonštrovaťGetAndContains (mapa), ktorý sa zobrazuje ďalej.

demonštrovaťGetAndContains (mapa)

/ ** * Predveďte Map.get (štáty) a Map.containsKey (štáty). * * @param map Mapa, na ktorej by sa malo demonštrovať. * / private static void proveďte ukážkuGetAndContains (konečná mapa mapy) {final StringBuilder demoResults = nový StringBuilder (); final String mapType = map.getClass (). getCanonicalName (); konečné štáty montana = štáty.MONTANA; demoResults.append (NEW_LINE); demoResults.append ("Mapa typu" + mapType + "vráti" + (map.get (montana)) + "pre Map.get () pomocou" + montana.getStateName ()); demoResults.append (NEW_LINE); demoResults.append ("Mapa typu" + mapType + "vráti" + (map.containsKey (montana)) + "pre Map.containsKey () pomocou" + montana.getStateName ()); demoResults.append (NEW_LINE); konečné štáty kansas = štáty.KANSAS; demoResults.append ("Mapa typu" + mapType + "vracia" + (map.get (kansas)) + "pre Map.get () pomocou" + kansas.getStateName ()); demoResults.append (NEW_LINE); demoResults.append ("Mapa typu" + mapType + "vracia" + (map.containsKey (kansas)) + "pre Map.containsKey () pomocou" + kansas.getStateName ()); demoResults.append (NEW_LINE); LOGGER.info (demoResults.toString ()); } 

Pre túto ukážku som zámerne nastavil Mapy tak, aby mali nulové kapitálové hodnoty pre Montanu, aby pre Kansas nemali vôbec žiadny vstup. To pomáha demonštrovať rozdiely v Map.get (objekt) a Map.containsKey (objekt). Pretože nie každý typ implementácie Mapy umožňuje nulové hodnoty, obklopil som časť, ktorá dáva Montanu bez veľkého kapitálu do bloku try / catch.

Ďalej sa zobrazia výsledky spustenia štyroch typov máp prostredníctvom kódu.

17. augusta 2010 23:23:26 dustin.examples.MapContainsZískať logMapInfo INFO: HashMap: {MONTANA = null, WASHINGTON = Olympia, ARIZONA = Phoenix, CALIFORNIA = Sacramento, WYOMING = Cheyenne, SOUTH_DAKOTA = Pierre, COLORADO = Denver = Sante Fe, NORTH_DAKOTA = Bismark, NEVADA = Carson City, OREGON = Salem, UTAH = Salt Lake City, IDAHO = Boise} 17. augusta 2010 23:23:26 dustin.examples.MapContains Získajte demonštráciuGetAndContains INFO: Mapa typu java. util.HashMap vráti null pre Map.get () pomocou Montana Map typu java.util.HashMap vráti true pre Map.containsKey () pomocou Montana Map typu java.util.HashMap vráti null pre Map.get () pomocou Kansas Map typu java.util.HashMap vráti hodnotu false pre Map.containsKey () pomocou Kansasu 17. augusta 2010 23:23:26 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. augusta 2010 23:23:26 dustin.examples.MapContainsGet combineGetAndContains INFO: Mapa typu java.util.LinkedHashMap vráti hodnotu null pre Map.get () pomocou mapy Montana typu java .util.LinkedHashMap vráti true pre Map.containsKey () pomocou Montana Map typu java.util.LinkedHashMap vráti null pre Map.get () pomocou Kansasu Mapa typu java.util.LinkedHashMap vráti false pre Map.containsKey () pomocou Kansasu 17. augusta 2010 23:23:26 dustin.examples.MapContainsGet generateStatesMap ŤAŽKÉ: java.util.concurrent.ConcurrentHashMap neumožňuje nulové hodnoty - java.lang.NullPointerException 17. augusta 2010 23:23:26 dustin.examples .MapContainsZískať logMapInfo INFO: ConcurrentHashMap: {SOUTH_DAKOTA = Pierre, ARIZONA = Phoenix, WYOMING = Cheyenne, UTAH = Salt Lake City, OREGON = Salem, CALIFORNIA = Sacramento, IDAHO = Boise, NEW_MEXICO = Sante FeD, COLORO = BARVA , WASHINGTON = Olympia, NEVADA = Carson City} 17. augusta 2010 23:23:26 dustin.examples.Ma pContainsGet manifestaGetAndContains INFO: Mapa typu java.util.concurrent.ConcurrentHashMap vráti null pre Map.get () pomocou Montana Mapa typu java.util.concurrent.ConcurrentHashMap vráti false pre Map.containsKey () pomocou Montana Mapy typu java.util .concurrent.ConcurrentHashMap vráti null pre Map.get () pomocou Kansasu Mapa typu java.util.concurrent.ConcurrentHashMap vráti false pre Map.containsKey () pomocou Kansasu 17. augusta 2010 23:23:26 dustin.examples.MapContainsZískať 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_DAKOTA = Pierre, UUT Lake City, WASHINGTON = Olympia, WYOMING = Cheyenne} 17. augusta 2010 23:23:26 dustin.examples.MapContainsGet proveďte demonstráciuGetAndContains INFO: Mapa typu java.util.EnumMap vráti hodnotu null pre Map.get () pomocou mapy Montana typu java.util.EnumMap vráti true pre Map.containsKey () pomocou Montana Map ty pe java.util.EnumMap vracia null pre Map.get () pomocou Kansasu Mapa typu java.util.EnumMap vracia false pre Map.containsKey () pomocou Kansasu 

Pre tri typy Map, pre ktoré som bol schopný vložiť nulové hodnoty, volanie Map.get (Object) vráti hodnotu null, aj keď metóda containsKey (Object) vráti pre Montanu hodnotu „true“, pretože som tento kľúč vložil do mapy bez hodnotu. Pre Kansas sú výsledky konzistentne Map.get () vracia null a Map.containsKey () vracia „false“, pretože v Mapách pre Kansas nie je žiadny záznam.

Vyššie uvedený výstup tiež ukazuje, že som nemohol vložiť nulovú hodnotu pre hlavné mesto Montany do ConcurrentHashMap implementácia (bola vyhodená NullPointerException).

17. augusta 2010 23:23:26 dustin.examples.MapContainsGet generateStatesMapSEVERE: java.util.concurrent.ConcurrentHashMap neumožňuje nulové hodnoty - java.lang.NullPointerException

To malo vedlajší efekt zachovania Map.get (objekt) a Map.containsKey (objekt) konzistentnejšie príslušné nulové a nepravé návratové hodnoty. Inými slovami, bolo nemožné mať kľúč na mape bez zodpovedajúcej nenulovej hodnoty.

V mnohých prípadoch použitie Map.get (objekt) funguje podľa potreby pre konkrétne konkrétne potreby, ale je lepšie si uvedomiť, že existujú rozdiely medzi nimi Map.get (objekt) a Map.containsKey (objekt) aby ste sa uistili, že sa vždy používa ten Je tiež zaujímavé poznamenať, že podobná je aj mapa containsValue (Object) metóda tiež.

Tu uvádzam celý zoznam kódov pre triedu MapContainsGet pre úplnosť:

MapContainsGet.java

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