Java >> Java-zelfstudie >  >> Tag >> HashMap

Gids voor Java IdentityHashMap

In deze zelfstudie leren we de Java IdentityHashMap in detail en de verschillen tussen IdentityHashMap en HashMap .

IdentityHashMap gebruikt referentiegelijkheid in plaats van objectgelijkheid bij het vergelijken van de sleutel (of waarden). Met andere woorden, in een IdentityHashMap , twee sleutels k1 en k2 worden als gelijk beschouwd als en slechts als (k1==k2) . We kunnen veranderlijke sleutels gebruiken in IdentityHashMap omdat referentiegelijkheid niet verandert met de toestand van het object.

1. Inleiding tot IdentityHashMap

De IdentityHashMap class (aanwezig in java.util pakket ) is een HashTable -gebaseerde implementatie van Kaart Interface en is aanwezig sinds Java versie 1.4 .

  • Deze les is niet een algemene kaart implementatie. Ook al implementeert deze klasse de Map interface, het schenkt het algemene contract van Map om de equals() te gebruiken methode bij het vergelijken van objecten. Het gebruikt referentiegelijkheid (==) om de sleutels op de kaart te doorzoeken . Deze klasse wordt alleen gebruikt wanneer referentiegelijkheid vereist is.
  • IdentityHashMap gebruikt intern de System.identityHashCode()-methode voor computergebruik
  • IdentityHashMap heeft bijna dezelfde functies als HashMap, inclusief de constructors en methoden. Wat de prestaties betreft, geeft het echter betere prestaties in vergelijking met HashMap, omdat het de voeringsondetechniek gebruikt van HashTable in vergelijking met de ketentechniek gebruikt door HashMap .
  • De iterators gooien ConcurrentModificationException tijdens een poging om de kaart aan te passen tijdens de iteratie.
  • Het is geen thread-safe klasse. Gebruik Collections.synchronizedMap() om een ​​thread-safe referentie van deze klasse te krijgen.

In Java-verzamelingen, de class is als volgt gedeclareerd:

public class IdentityHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Serializable, Cloneable

Zoals hierboven getoond, implementeert het Map interface en breidt AbstractMap uit klasse.

2. Werken met IdentityHashMap

2.1 IdentityHashMap maken

We kunnen IdentityHashMap . maken door gebruik te maken van de volgende constructors:

  • IdentityHashMap() : Wordt gebruikt om een ​​lege kaart te maken met de initiële standaardcapaciteit van 21 .
  • IdentityHashMap(int initialCapacity) : Wordt gebruikt om een ​​lege kaart te maken met de opgegeven initiële capaciteit.
  • IdentityHashMap(Map m) : Gebruikt om een ​​nieuwe IdentityHashMap te maken met dezelfde items als de opgegeven kaart.
IdentityHashMap<String, String> map = new IdentityHashMap<>();

IdentityHashMap<String, String> map = new IdentityHashMap<>(16);

Map<String, String> map = new HashMap<String, String>() {{
    put("key1", "value1");
   put("key2", "value2");
}};
IdentityHashMap<String, String> map = new IdentityHashMap<>(map);

2.2 IdentityHashMap Methoden

Enkele veelgebruikte methoden in deze klasse zijn:

  • Object put(key, value): Voegt een sleutel/waarde-paar in op de kaart.
  • Object get(key): geeft de waarde terug voor de opgegeven sleutel op de kaart.
  • boolean containsKey(key): retourneert true of false op basis van of de opgegeven sleutel op de kaart wordt gevonden of niet.
  • boolean containsValue(value): Vergelijkbaar met containsKey() methode, zoekt het naar de opgegeven waarde in plaats van naar de sleutel.
  • Set keySet(): geeft de Set . terug van alle sleutels die op de kaart zijn opgeslagen.
  • Set entrySet(): geeft de Set . terug van alle toewijzingen die op de kaart zijn opgeslagen.
  • Value remove(Object key): verwijdert het sleutel-waarde-paar voor de opgegeven sleutel.
  • int size(): geeft de kaartgrootte terug die gelijk is aan het aantal sleutel-waardeparen dat is opgeslagen in de kaart .

2.3 IdentityHashMap Voorbeeld

Laten we snel een voorbeeld bespreken van het maken van de instantie en hoe we de hierboven beschreven methoden kunnen gebruiken.

//Creating IdentityHashMap
IdentityHashMap<Integer, String> map = new IdentityHashMap<>();

//Adding values to map using put()
map.put(1, "A");
map.put(2, "B");

map.put(3, "C");
System.out.println(map);

//Getting a value from the map
String value = map.get(2);
System.out.println(value);

//Checking if a key or value present in the map
System.out.println(map.containsKey(3));
System.out.println(map.containsValue("Z"));

//Removing an entry
map.remove(3);
System.out.println(map);

//Finding map size
System.out.println(map.size());

//Iterating over the map
for(Map.Entry<Integer, String> entry : map.entrySet())
{
    System.out.println(entry.getKey() + " :: " + entry.getValue());
}

Merk op dat IdentityHashMap ondersteunt null sleutels en waarden.

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

map.put(null, "Some Value");   //Null key 
map.put("Some Key", null);      //Null value

3. Verschil tussen HashMap en IdentityHashMap

3.1 Referentiegelijkheid

IdentityHashMap gebruikt referentiegelijkheid (==) over de Kaarten is gelijk aan () methode bij het vergelijken van sleutels (en waarden). Laten we het met een voorbeeld begrijpen.

// Two similar keys but different instances in memory
Integer key1 = new Integer(10);
Integer key2 = new Integer(10);

// Same keys in IdentityHashMap
IdentityHashMap<Integer, String> identityHashMap = new IdentityHashMap<>();
identityHashMap.put(key1, "India");
identityHashMap.put(key2, "USA");

System.out.println("Identity HashMap : " + identityHashMap);

// Same keys in HashMap
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(key1, "India");
hashMap.put(key2, "USA");

System.out.println("HashMap : " + hashMap);

Let op de uitvoer van het programma. HashMap de tweede sleutel afgewezen omdat deze de sleutels vergelijkt met equals() methode en voor beide sleutels is de waarde 10. IdentityHashMap gebruikt referentie-gelijkheid, en beide sleutels worden afzonderlijk in het geheugen opgeslagen, zodat hun referentie ongelijk zal zijn.

Wanneer we het sleutel-waardepaar in HashMap plaatsen , het werkt het vorige item bij en we krijgen een enkel item opgeslagen in de kaart.

Identity HashMap : {10=USA, 10=India}
HashMap : {10=USA}

3.2 Mutable Keys

We kunnen veranderlijke sleutels gebruiken in IdentityHashMap terwijl voor HashMap het wordt altijd aanbevolen om onveranderlijke sleutels te gebruiken.

Laten we het met een voorbeeld begrijpen en een veranderlijke klasse 'Vehicle . maken ’. Definieer de benodigde accessor-methoden, hashCode() en equals()-methoden.

class Vehicle {

  private String name;
  private int year;

  public Vehicle(String name, int year) {
    this.name = name;
    this.year = year;
  }

  //Getters and Setters

  @Override
  public String toString() {
    return "Vehicle{" +
        "vehicleName='" + name + '\'' +
        ", modelYear=" + year +
        '}';
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Vehicle vehicle = (Vehicle) o;

    if (Objects.equals(year, vehicle.year)) return false;
    return Objects.equals(name, vehicle.name);
  }

  @Override
  public int hashCode() {
    int result = name != null ? name.hashCode() : 0;
    result = 31 * result + year;
    return result;
  }
}

We zullen een paar sleutel-waarde-paren aan de kaart toevoegen en vervolgens de status van de sleutel en waarde wijzigen. Vervolgens halen we de invoer op met de gewijzigde sleutel, die de oorspronkelijke waarde zou moeten retourneren.

Vehicle vehicle = new Vehicle("Honda", 2015);

Map<Vehicle, String> identityHashMap1 = new IdentityHashMap<>();
identityHashMap1.put(vehicle, "Old Vehicle");

// Changing key state
vehicle.setName("Modified Vehicle");
vehicle.setYear(2022);

// Getting value for key vehicle from the map
System.out.println( identityHashMap1.get(vehicle) );   //Prints 'Modified Vehicle'

4. IdentityHashMap Toepassingen

IdentityHashMap wordt in zeldzame gevallen gebruikt en we moeten voorzichtig zijn bij het gebruik van deze klasse.

Het helpt bij het bouwen van specifieke kaders, waaronder:

  • Springbonen of Singleton-soorten omdat ze precies één exemplaar van bepaalde typen beheren
  • Behoud van proxy-objecten voor een set veranderlijke objecten
  • Klasse-objecten omdat ze ook door verwijzing vergelijkbaar zijn.
  • Instances in cache op basis van een objectreferentie
  • Een in-memory grafiek van objecten bijhouden met referentie

5. Conclusie

We leerden over IdentityHashMap in Java, de interne werking en hoe het verschilt van HashMap . We hebben ook praktische voorbeelden behandeld waarbij zowel HashMap &IdentityHashMap en hoe ze zich anders gedragen bij het vergelijken van toetsen.

Veel plezier met leren !!


Java-tag