Java >> Java tutorial >  >> Tag >> class

Java IdentityHashMap Class og dens brugssager

1. Oversigt

I dette selvstudie lærer vi, hvordan du bruger IdentityHashMap klasse i Java. Vi vil også undersøge, hvordan det adskiller sig fra det generelle HashMap klasse. Selvom denne klasse implementerer Kort grænseflade, overtræder det kontrakten for kortet grænseflade .

For mere detaljeret dokumentation kan vi henvise til IdenityHashMap java doc side. For flere detaljer om det generelle HashMap klasse, kan vi læse A Guide to Java HashMap.

2. Om IdentityHashMap Klasse

Denne klasse implementerer kortet interface. Kort grænsefladen kræver brug af equals() metode på nøglesammenligningen. Men IdentityHashMap klasse overtræder den kontrakt. I stedet bruger den referencelighed (==) på vigtige søgeoperationer .

Under søgeoperationer, HashMap bruger hashCode() metode til hashing, hvorimod IdentityHashMap bruger System.identityHashCode() metode. Den bruger også hashtabellens lineære probeteknik til søgeoperationer.

Brugen af ​​referencelighed, System.identityHashCode(), og den lineære probe-teknik giver IdentityHashMap klasse en bedre præstation.

3. Brug af IdentityHashMap Klasse

Objektkonstruktion og metodesignaturer er de samme som HashMap, men adfærden er anderledes på grund af referencelighed.

3.1. Oprettelse af IdentityHashMap Objekter

Vi kan oprette det ved at bruge standardkonstruktøren:

IdentityHashMap<String, String> identityHashMap = new IdentityHashMap<>();

Eller det kan oprettes ved hjælp af den oprindelige forventede kapacitet:

IdentityHashMap<Book, String> identityHashMap = new IdentityHashMap<>(10);

Hvis vi ikke angiver den oprindelige expectedCapcity parameter, som vi gjorde ovenfor, bruger den 21 som standardkapacitet.

Vi kan også oprette det ved hjælp af et andet kortobjekt:

IdentityHashMap<String, String> identityHashMap = new IdentityHashMap<>(otherMap);

I dette tilfælde initialiserer den det oprettede identityHashMap med indtastningerne fra otherMap .

3.2. Tilføj, hent, opdater og fjern poster

put() metode bruges til at tilføje en post:

identityHashMap.put("title", "Harry Potter and the Goblet of Fire");
identityHashMap.put("author", "J. K. Rowling");
identityHashMap.put("language", "English");
identityHashMap.put("genre", "Fantasy");

Vi kan også tilføje alle indgange fra det andet kort ved at bruge putAll() metode:

identityHashMap.putAll(otherMap);

For at hente værdier bruger vi get() metode:

String value = identityHashMap.get(key);

For at opdatere en værdi for en nøgle bruger vi put() metode:

String oldTitle = identityHashMap.put("title", "Harry Potter and the Deathly Hallows");
assertEquals("Harry Potter and the Goblet of Fire", oldTitle);

I ovenstående uddrag, put() metode returnerer den gamle værdi efter opdateringen. Den anden sætning sikrer, at oldTitle matcher den tidligere "titel"-værdi.

Vi kan bruge remove() metode til at fjerne et element:

identityHashMap.remove("title");

3.3. Gentag gennem alle poster

Vi kan iterere gennem alle indtastningerne ved hjælp af entitySet() metode:

Set<Map.Entry<String, String>> entries = identityHashMap.entrySet();
for (Map.Entry<String, String> entry: entries) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

Vi kan også iterere gennem alle indtastningerne ved hjælp af keySet() metode:

for (String key: identityHashMap.keySet()) {
    System.out.println(key + ": " + identityHashMap.get(key));
}

Disse iteratorer bruger en fejl-hurtig mekanisme. Hvis kortet ændres under iteration, kaster det en ConcurrentModificationException .

3.4. Andre metoder

Vi har også forskellige metoder tilgængelige, der fungerer på samme måde som andre Kort objekter:

  • clear() :fjerner alle poster
  • containsKey() :finder, om der findes en nøgle på kortet eller ej. Kun referencer sidestilles
  • containsValue() :finder om værdien findes på kortet. Kun referencer sidestilles
  • keySet() :returnerer et identitetsbaseret nøglesæt
  • størrelse() :returnerer antallet af poster
  • værdier() :returnerer en samling af værdier

3.5. Support til Null Nøgler og Null Værdier

IdentityHashMap tillader null for både nøglen og værdien:

IdentityHashMap<String, String> identityHashMap = new IdentityHashMap<>();
identityHashMap.put(null, "Null Key Accepted");
identityHashMap.put("Null Value Accepted", null);
assertEquals("Null Key Accepted", identityHashMap.get(null));
assertEquals(null, identityHashMap.get("Null Value Accepted"));

Ovenstående kodestykke sikrer null både som nøgle og værdi.

3.6. Samtidighed med IdentityHashMap

IdentityHashMap er ikke trådsikker , det samme som HashMap . Så hvis vi har flere tråde at få adgang til/ændre IdentityHashMap poster parallelt, bør vi konvertere dem til det synkroniserede kort.

Vi kan få et synkroniseret kort ved hjælp af Samlingerne klasse:

Map<String, String> synchronizedMap = Collections.synchronizedMap(new IdentityHashMap<String, String>());

4. Eksempel på brug af referencelighed

IdentityHashMap bruger referencelighed (==) over equals() metode til at søge/gemme/ få adgang til nøgleobjekter.

Et IdentityHashMap oprettet med fire egenskaber:

IdentityHashMap<String, String> identityHashMap = new IdentityHashMap<>();
identityHashMap.put("title", "Harry Potter and the Goblet of Fire");
identityHashMap.put("author", "J. K. Rowling");
identityHashMap.put("language", "English");
identityHashMap.put("genre", "Fantasy");

Endnu et HashMap oprettet med de samme egenskaber:

HashMap<String, String> hashMap = new HashMap<>(identityHashMap);
hashMap.put(new String("genre"), "Drama");
assertEquals(4, hashMap.size());

Når du bruger et nyt strengobjekt genre" som en nøgle, HashMap sidestiller den med den eksisterende nøgle og opdaterer værdien. Størrelsen af ​​hash-kortet forbliver derfor den samme som 4.

Følgende kodestykke viser hvordan IdentityHashMap opfører sig anderledes:

identityHashMap.put(new String("genre"), "Drama");
assertEquals(5, identityHashMap.size());

IdentityHashMap betragter det nye "genre"-strengobjekt som en ny nøgle. Derfor hævder det, at størrelsen er 5. To forskellige objekter af "genre" bruges som to nøgler med Drama og Fantasy som værdier.

5. Foranderlige nøgler

IdentityHashMap tillader foranderlige nøgler . Dette er endnu en nyttig funktion i denne klasse.

Her tager vi en simpel bog klasse som et foranderligt objekt:

class Book {
    String title;
    int year;
    
    // other methods including equals, hashCode and toString
}

Først to foranderlige objekter i Book klasse oprettes:

Book book1 = new Book("A Passage to India", 1924);
Book book2 = new Book("Invisible Man", 1953);

Følgende kode viser foranderlig nøglebrug med HashMap :

HashMap<Book, String> hashMap = new HashMap<>(10);
hashMap.put(book1, "A great work of fiction");
hashMap.put(book2, "won the US National Book Award");
book2.year = 1952;
assertEquals(null, hashMap.get(book2));

Selvom bog2 post er til stede i HashMap , den kunne ikke hente sin værdi. Fordi den er blevet ændret og lig med() metoden er nu ikke lig med det modificerede objekt. Det er derfor det generelle Kort objekter mandaterer uforanderlige objekter som en nøgle.

Nedenstående uddrag bruger de samme foranderlige nøgler med IdentityHashMap :

IdentityHashMap<Book, String> identityHashMap = new IdentityHashMap<>(10);
identityHashMap.put(book1, "A great work of fiction");
identityHashMap.put(book2, "won the US National Book Award");
book2.year = 1951;
assertEquals("won the US National Book Award", identityHashMap.get(book2));

Interessant nok IdentityHashMap er i stand til at hente værdier, selv når nøgleobjektet er blevet ændret. I ovenstående kode, assertEquals sikrer, at den samme tekst hentes igen. Dette er muligt på grund af referencelighed.

6. Nogle brugssager

Som et resultat af dets funktioner, IdentiyHashMap adskiller sig fra andre Kort genstande. Det bruges dog ikke til generelle formål, og derfor skal vi være forsigtige, når vi bruger denne klasse.

Det er nyttigt til at bygge specifikke rammer, herunder:

  • Vedligeholdelse af proxy-objekter for et sæt af mutable objekter
  • Opbygning af en hurtig cache baseret på en objektreference
  • Bevaring af en graf i hukommelsen af ​​objekter med referencer

7. Konklusion

I denne artikel lærte vi, hvordan man arbejder med IdentityHashMap , hvordan det adskiller sig fra almindelige HashMap , og nogle use cases.

Et komplet kodeeksempel kan findes på GitHub.


Java tag