Προγραμματισμός

Java Map.get και Map.containsKey

Όταν χρησιμοποιείτε εφαρμογές Java Map, είναι μερικές φορές κοινό να επικαλέσετε το ΧάρτηςΗ μέθοδος get (Object) και η αντίδραση διαφορετικά με βάση το αν η τιμή που επιστρέφεται είναι μηδενική ή όχι. Μια κοινή υπόθεση μπορεί να γίνει ότι ένα μηδενικό που επιστρέφεται από το Map.get (Object) υποδεικνύει ότι δεν υπάρχει καταχώριση με το παρεχόμενο κλειδί στο χάρτη, αλλά αυτό δεν συμβαίνει πάντα. Πράγματι, εάν μια Java Χάρτης Η εφαρμογή επιτρέπει μηδενικές τιμές, τότε είναι δυνατό για το Χάρτης για να επιστρέψει την τιμή του για το δεδομένο κλειδί, αλλά αυτή η τιμή μπορεί να είναι μηδενική. Συχνά αυτό δεν έχει σημασία, αλλά αν ισχύει, μπορεί κανείς να χρησιμοποιήσει το Map.containsKey () για να προσδιορίσει εάν το Χάρτης Η καταχώριση έχει μια βασική καταχώριση. Εάν το κάνει και το Χάρτης επιστρέφει μηδενικό σε μια κλήση λήψης για το ίδιο κλειδί, τότε είναι πιθανό ότι το κλειδί αντιστοιχεί σε ένα μηδενικό αξία. Με άλλα λόγια, αυτό Χάρτης μπορεί να επιστρέψει "αλήθεια" για περιέχειKey (Αντικείμενο) ενώ ταυτόχρονα επιστρέφει " μηδενικό" Για λήψη (Αντικείμενο). Υπάρχουν μερικά Χάρτης υλοποιήσεις που δεν επιτρέπουν μηδενικό αξίες. Σε αυτές τις περιπτώσεις, α μηδενικό από μια κλήση "get" θα πρέπει να ταιριάζει σταθερά με μια επιστροφή "false" από τη μέθοδο "περιέχειKey".

Σε αυτήν την ανάρτηση ιστολογίου, παρουσιάζω αυτές τις πτυχές του Map.get (Αντικείμενο) και Map.containsKey (Αντικείμενο). Πριν πάω σε αυτήν την επίδειξη, θα επισημάνω πρώτα ότι η τεκμηρίωση του Javadoc για το Map.get (Object) προειδοποιεί ρητά για τις λεπτές διαφορές μεταξύ Map.get (Αντικείμενο) και Map.containsKey (Αντικείμενο):

Εάν αυτός ο χάρτης επιτρέπει μηδενικές τιμές, τότε μια τιμή επιστροφής του μηδενικό δεν σημαίνει απαραίτητα ότι ο χάρτης δεν περιέχει αντιστοίχιση για το κλειδί. Είναι επίσης πιθανό ο χάρτης να αντιστοιχεί ρητά στο κλειδί μηδενικό. ο περιέχει Κέι λειτουργία μπορεί να χρησιμοποιηθεί για τη διάκριση αυτών των δύο περιπτώσεων.

Για τα παραδείγματα της ανάρτησης, θα χρησιμοποιήσω τον αριθμό των κρατών που ορίζεται στη συνέχεια:

States.java

πακέτο dustin.example; / ** * Enum που αντιπροσωπεύει επιλεγμένες δυτικές πολιτείες στις Ηνωμένες Πολιτείες. * / public enum States {ARIZONA ("Arizona"), CALIFORNIA ("California"), COLORADO ("Colorado"), IDAHO ("Idaho"), KANSAS ("Κάνσας"), MONTANA ("Montana"), NEVADA ( "Νεβάδα"), NEW_MEXICO ("Νέο Μεξικό"), NORTH_DAKOTA ("Βόρεια Ντακότα"), OREGON ("Όρεγκον"), SOUTH_DAKOTA ("Νότια Ντακότα"), UTAH ("Γιούτα"), Ουάσιγκτον ("Ουάσιγκτον"), WYOMING ("Ουαϊόμινγκ"); / ** Όνομα πολιτείας. * / ιδιωτικό String stateName; / ** * Παραμετροποιημένος κατασκευαστής enum που δέχεται ένα όνομα κατάστασης. * * @param newStateName Όνομα της πολιτείας. * / States (final String newStateName) {this.stateName = newStateName; } / ** * Δώστε το όνομα της πολιτείας. * * @return Όνομα της πολιτείας * / public String getStateName () {return this.stateName; }} 

Η επόμενη λίστα κωδικών χρησιμοποιεί το παραπάνω enum και συμπληρώνει έναν χάρτη πολιτειών στις πρωτεύουσες τους. Η μέθοδος δέχεται μια κλάση που θα πρέπει να είναι η συγκεκριμένη εφαρμογή του Χάρτη που θα δημιουργηθεί και θα συμπληρωθεί.

createStatesMap (κλάση)

/ ** * Δημιουργία και συμπλήρωση χάρτη καταστάσεων σε πρωτεύουσες με τον παρεχόμενο τύπο χάρτη. * Αυτή η μέθοδος καταγράφει επίσης τυχόν υλοποιήσεις χάρτη για τις οποίες δεν επιτρέπονται μηδενικές τιμές. * * @param mapClass Τύπος χάρτη που θα δημιουργηθεί. * @ return Χάρτης των πολιτειών στις πρωτεύουσες. * / private static Map createStatesMap (Class mapClass) {Map mapToPopulate = null; εάν (Map.class.isAssignableFrom (mapClass)) {δοκιμάστε {mapToPopulate = mapClass! = EnumMap.class? (Χάρτης) mapClass.newInstance (): getEnumMap (); mapToPopulate.put (States.ARIZONA, "Phoenix"); mapToPopulate.put (States.CALIFORNIA, "Sacramento"); mapToPopulate.put (States.COLORADO, "Ντένβερ"); 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, "Cheyenne"); δοκιμάστε το {mapToPopulate.put (States.MONTANA, null); } catch (NullPointerException npe) {LOGGER.severe (mapToPopulate.getClass (). getCanonicalName () + "δεν επιτρέπει τιμές null -" + npe.toString ()); }} catch (InstantiationException instantiationException) {LOGGER.log (Level.SEVERE, "Unable to instantiate Map of type" + mapClass.getName () + instantiationException.toString (), instantiationException); } catch (IllegalAccessException illegalAccessException) {LOGGER.log (Level.SEVERE, "Δεν είναι δυνατή η πρόσβαση στο Map of type" + mapClass.getName () + haramAccessException.toString (), haramAccessException) }} αλλιώς {LOGGER.warning ("Παρεχόμενος τύπος δεδομένων" + mapClass.getName () + "δεν είναι Χάρτης."); } επιστροφή mapToPopulate; } 

Η παραπάνω μέθοδος μπορεί να χρησιμοποιηθεί για τη δημιουργία Χαρτών διαφόρων ειδών. Δεν εμφανίζω τον κώδικα αυτή τη στιγμή, αλλά το παράδειγμά μου δημιουργεί αυτούς τους Χάρτες με τέσσερις συγκεκριμένες υλοποιήσεις: HashMap, LinkedHashMap, ConcurrentHashMap και EnumMap. Καθεμία από αυτές τις τέσσερις εφαρμογές στη συνέχεια εκτελείται μέσω της μεθόδου demonstrGetAndContains (Χάρτης), το οποίο εμφανίζεται στη συνέχεια.

demonstrGetAndContains (Χάρτης)

/ ** * Επίδειξη του Map.get (States) και του Map.containsKey (States). * * Χάρτης @param Χάρτης πάνω στον οποίο θα πρέπει να διεξάγεται επίδειξη. * / private static void demonstrGetAndContains (τελικός χάρτης χάρτη) {final StringBuilder demoResults = new StringBuilder (); final String mapType = map.getClass (). getCanonicalName (); final States montana = States.MONTANA; demoResults.append (NEW_LINE); demoResults.append ("Map of type" + mapType + "Return" + (map.get (montana)) + "for Map.get () using" + montana.getStateName ()); demoResults.append (NEW_LINE); demoResults.append ("Map of type" + mapType + "Return" + (map.containsKey (montana)) + "for Map.containsKey () χρησιμοποιώντας" + montana.getStateName ()); demoResults.append (NEW_LINE); final States kansas = States.KANSAS; demoResults.append ("Map of type" + mapType + "Return" + (map.get (kansas)) + "for Map.get () using" + kansas.getStateName ()); demoResults.append (NEW_LINE); demoResults.append ("Map of type" + mapType + "Return" + (map.containsKey (kansas)) + "for Map.containsKey () χρησιμοποιώντας" + kansas.getStateName ()); demoResults.append (NEW_LINE); LOGGER.info (demoResults.toString ()); } 

Για αυτήν την επίδειξη, έθεσα σκόπιμα τους Χάρτες ώστε να έχουν μηδενικές κεφαλαιακές τιμές για τη Μοντάνα ώστε να μην έχουν καθόλου είσοδο για το Κάνσας. Αυτό βοηθά στην απόδειξη των διαφορών στο Map.get (Αντικείμενο) και Map.containsKey (Αντικείμενο). Επειδή δεν επιτρέπει κάθε τύπος εφαρμογής χάρτη για μηδενικές τιμές, περικύκλωσα το τμήμα που βάζει τη Μοντάνα χωρίς κεφάλαια μέσα σε ένα μπλοκ δοκιμής.

Τα αποτελέσματα της εκτέλεσης των τεσσάρων τύπων χαρτών μέσω του κώδικα εμφανίζονται στη συνέχεια.

17 Αυγούστου 2010 11:23:26 μμ = Sante Fe, NORTH_DAKOTA = Bismark, NEVADA = Carson City, OREGON = Salem, UTAH = Salt Lake City, IDAHO = Boise} 17 Αυγούστου 2010 11:23:26 μμ dustin.examples.MapContainsGet demonstrGetAndContains INFO: Χάρτης τύπου java. util.HashMap επιστρέφει null για Map.get () χρησιμοποιώντας Montana Map του τύπου java.util.HashMap επιστρέφει true για Map.containsKey () χρησιμοποιώντας Montana Map του τύπου java.util.HashMap επιστρέφει null για το Map.get () χρησιμοποιώντας το Kansas Map του τύπου java.util.HashMap επιστρέφει false για το Map.containsKey () χρησιμοποιώντας το Kansas 17 Αυγούστου 2010 11:23:26 μμ dustin.examples.MapContainsGet logMapInfo INFO: LinkedHashMap: {ARIZONA = Phoenix, CALIFORNIA = Sacramento, COLORADO = Ντένβερ, 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 Αυγούστου 2010 11:23:26 μμ dustin.examples.MapContainsGet demonstrGetAndContains INFO: Χάρτης του τύπου java.util.LinkedHashMap επιστρέφει null για το Map.get () χρησιμοποιώντας το Montana Map of type java Το .util.LinkedHashMap επιστρέφει true για το Map.containsKey () χρησιμοποιώντας το χάρτη Montana του τύπου java.util.LinkedHashMap επιστρέφει null για το Map.get () χρησιμοποιώντας το χάρτη του Κάνσας του τύπου java.util.LinkedHashMap επιστρέφει false για το Map.containsKey () χρησιμοποιώντας το Kansas Αυγ 17, 2010 11:23:26 μμ dustin.examples.MapContainsGet createStatesMap SEVERE: java.util.concurrent.ConcurrentHashMap δεν επιτρέπει μηδενικές τιμές - java.lang.NullPointerException 17 Αυγούστου 2010 11:23:26 μ.μ. dustin.examples .MapContainsGet logMapInfo ΠΛΗΡΟΦΟΡΙΕΣ: ConcurrentHashMap: {SOUTH_DAKOTA = Pierre, ARIZONA = Phoenix, WYOMING = Cheyenne, UTAH = Salt Lake City, OREGON = Salem, CALIFORNIA = Sacramento, IDAHO = Boise, NEW_MEXICO = Santo, NORO , WASHINGTON = Olympia, NEVADA = Carson City} 17 Αυγ 2010 11:23:26 μμ dustin.examples.Ma pContainsGet demonstrGetAndContains INFO: Χάρτης τύπου java.util.concurrent.ConcurrentHashMap επιστρέφει null για Map.get () χρησιμοποιώντας Montana Map του τύπου java.util.concurrent.ConcurrentHashMap επιστρέφει false για Map.containsKey () χρησιμοποιώντας Montana Χάρτης τύπου java.util Το .concurrent.ConcurrentHashMap επιστρέφει null για το Map.get () χρησιμοποιώντας το Kansas Map του τύπου java.util.concurrent.ConcurrentHashMap επιστρέφει false για Map.containsKey () χρησιμοποιώντας το Kansas 17 Αυγούστου 2010 11:23:26 PM dustin.examples.MapContainsGet logMapInfo ΠΛΗΡΟΦΟΡΙΕΣ: EnumMap: {ARIZONA = Phoenix, CALIFORNIA = Sacramento, COLORADO = Denver, IDAHO = Boise, MONTANA = null, NEVADA = Carson City, NEW_MEXICO = Sante Fe, NORTH_DAKOTA = Bismark, OREGON = Salem, SOUTH = SOUTH Lake City, WASHINGTON = Olympia, WYOMING = Cheyenne} 17 Αυγούστου 2010 11:23:26 μμ dustin.examples.MapContainsGet demonstrGetAndContains INFO: Χάρτης τύπου java.util.EnumMap επιστρέφει null για το Map.get () χρησιμοποιώντας Montana Map of type Το java.util.EnumMap επιστρέφει true για το Map.containsKey () χρησιμοποιώντας το Montana Map of ty pe java.util.EnumMap επιστρέφει null για το Map.get () χρησιμοποιώντας το Kansas Map του τύπου java.util.EnumMap επιστρέφει false για το Map.containsKey () χρησιμοποιώντας το Kansas 

Για τους τρεις τύπους χάρτη για τους οποίους μπόρεσα να εισαγάγω μηδενικές τιμές, η κλήση Map.get (Object) επιστρέφει null ακόμη και όταν η μέθοδος περιέχειKey (Object) επιστρέφει "true" για Montana επειδή έβαλα αυτό το κλειδί στο χάρτη αξία. Για το Κάνσας, τα αποτελέσματα είναι σταθερά το Map.get () επιστρέφει null και το Map.containsKey () επιστρέφει "false" επειδή δεν υπάρχει καμία καταχώρηση στους Χάρτες για το Κάνσας.

Το παραπάνω αποτέλεσμα δείχνει επίσης ότι δεν μπορούσα να βάλω μια μηδενική τιμή για την πρωτεύουσα της Μοντάνα στο ΤαυτόχρονηHashMap υλοποίηση (ρίχτηκε ένα NullPointerException).

Αυγ 17, 2010 11:23:26 μμ dustin.examples.MapContainsGet createStatesMapSEVERE: java.util.concurrent.ConcurrentHashMap δεν επιτρέπει μηδενικές τιμές - java.lang.NullPointerException

Αυτό είχε την παρενέργεια της διατήρησης Map.get (Αντικείμενο) και Map.containsKey (Αντικείμενο) πιο συνεπείς αντίστοιχες μηδενικές και ψευδείς τιμές επιστροφής. Με άλλα λόγια, ήταν αδύνατο να υπάρχει ένα κλειδί στο χάρτη χωρίς να έχει αντίστοιχη μη μηδενική τιμή.

Σε πολλές περιπτώσεις, χρήση του Map.get (Αντικείμενο) λειτουργεί όπως απαιτείται για τις συγκεκριμένες ανάγκες, αλλά είναι καλύτερο να θυμόμαστε ότι υπάρχουν διαφορές μεταξύ τους Map.get (Αντικείμενο) και Map.containsKey (Αντικείμενο) για να βεβαιωθείτε ότι χρησιμοποιείται το κατάλληλο. Είναι επίσης ενδιαφέρον να σημειωθεί ότι ο χάρτης διαθέτει παρόμοιο περιέχει τιμή (αντικείμενο) μέθοδος επίσης.

Παραθέτω ολόκληρη την καταχώριση κώδικα για την κατηγορία MapContainsGet εδώ για πληρότητα:

MapContainsGet.java