📜  实现 IdentityHashMap API 的Java程序

📅  最后修改于: 2022-05-13 01:55:34.907000             🧑  作者: Mango

实现 IdentityHashMap API 的Java程序

IdentityHashMap 使用 Hashtable 实现 Map 接口,在比较键(和值)时使用引用相等代替对象相等。这个类不是一个通用的 Map 实现。虽然这个类实现了 Map 接口,但它故意违反了 Map 的一般约定,即在比较对象时强制使用 equals() 方法。当用户需要通过引用来比较对象时,将使用此类。它属于Java.util包。它后来被添加到Java 1.4 中

JavaIdentityHashMap和HashMap的主要区别在于IdentityHashMap是Map接口的一种特殊实现,它不像其他Map实现,例如HashMap,不使用equals(obj)和hashCode()方法来比较对象。相反,IdentityHashMap 使用相等运算符“==”来比较Java的键和值,这使它比 HashMap 更快,并且适合需要引用相等性检查而不是逻辑相等性的地方。

IdentityHashMap 和 HashMap 的区别如下:

  1. HashMap 与 IdentityHashMap 的主要区别在于 IdentityHashMap 使用相等运算符“==”来比较 Map 内部的键和值,而 HashMap 使用 equals(obj) 方法来比较键和值。
  2. 由于 IdentityHashMap 不使用 equals(obj),对于具有昂贵的 equals(obj) 和 hashCode() 的对象,它比 HashMap 相对更快。
  3. HashMap 和 IdentityHashMap 之间的另一个区别是键的不变性。安全的基本要求之一,当我们在 HashMap 中存储对象时,键需要是不可变的,IdentityHashMap 不要求键是不可变的,因为它不依赖于 equals(obj) 和 hashCode()。

示例 1:



Java
// Java Program to illustrate IdentityHashMap by
// Differenciating between HashMap and IdentityHashMap
 
// Importing input output classes
import java.io.*;
// Importing HashMap, IdentityHashMap and Map classes
// from java.util package
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
 
// Main Class
public class GFG {
 
    // Main driver method
    public static void main (String[] args) {
 
        // Creating objects of HashMap and IdentityHashMap objects
        // Declaring objects of type String and Integer type
        Map hashMap = new HashMap();
        Map identityHashMap = new IdentityHashMap();
 
        // Adding elements to objects of Maps created above
        // Elements are of type key-value pairs using put() method
        // Custom entries
        hashMap.put("Scala", 100);
        hashMap.put(new String("Scala"), 101);
        hashMap.put("Groovy", 56);
        hashMap.put(new String("Groovy"), 57);
 
        identityHashMap.put("Ruby", 25);
        identityHashMap.put(new String("Ruby"), 27);
        identityHashMap.put("Swift", 12);
        identityHashMap.put(new String("Swift"), 13);
 
 
        // hashMap.size() will print 2 since
        // it compares the objects logically and both the keys are same
        System.out.println("Size of HashMap is : " + hashMap.size());
 
        // identityHashMap.size() will print 4 since
        // it compares the objects by reference
        System.out.println("Size of IdentityHashMap is : " + identityHashMap.size());
    }
}


Java
// Java Program to illustrate IdentityHashMap by
// Differenciating between HashMap and IdentityHashMap
 
// Importing input output classes
import java.io.*;
// Importing Map,HashMap and IdentityHashMap classes
// from java.util package
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
 
// Class 1
// Helper Class
class ProgrammingLanguage {
 
    // Member variables of this class
    private String language;
    private Integer value;
 
    // Constructor of this class
    public ProgrammingLanguage(String language,
                               Integer value)
    {
 
        // this keyword refers to current objectc itself
        this.language = language;
        this.value = value;
    }
 
    // Method 1
    public String getlanguage()
    {
 
        // Returning language
        return language;
    }
 
    // Method 2
    public Integer getValue()
    {
 
        // Returning value associated with a language
        return value;
    }
 
    // Method 3
    // Sets a new value for a languauge
    public void setValue(Integer value)
    {
        this.value = value;
    }
 
    // Method 4
    // @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result
            = prime * result
              + ((language == null) ? 0 : value.hashCode());
        result
            = prime * result
              + ((language == null) ? null
                                    : language.hashCode());
        return result;
    }
 
    // Method 5
    // @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ProgrammingLanguage other
            = (ProgrammingLanguage)obj;
        if (value == null) {
            if (other.value != null)
                return false;
        }
        else if (!value.equals(other.value))
            return false;
        if (language == null) {
            if (other.language != null)
                return false;
        }
        else if (!language.equals(other.language))
            return false;
        return true;
    }
}
 
// Class 2
// Main Class
public class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        ProgrammingLanguage groovy
            = new ProgrammingLanguage("Groovy", 1000);
        ProgrammingLanguage scala
            = new ProgrammingLanguage("Scala", 2000);
        ProgrammingLanguage ruby
            = new ProgrammingLanguage("Ruby", 3000);
 
        Map languageValue
            = new HashMap<>();
        Map
            languageValueIdentity = new IdentityHashMap<>();
 
        // Inserting elements to object of HashMap created
        // Custom entries
        languageValue.put(groovy, groovy.getValue());
        languageValue.put(scala, scala.getValue());
        languageValue.put(ruby, ruby.getValue());
 
        // Inserting elements to object of IdenityHashMap
        // created Custom entries
        languageValueIdentity.put(groovy,
                                  groovy.getValue());
        languageValueIdentity.put(scala, scala.getValue());
        languageValueIdentity.put(ruby, ruby.getValue());
 
        // Display message only
        System.out.println("Before modifying keys  :  ");
 
        String result = languageValue.get(groovy) != null
                            ? "Yes"
                            : "No";
 
        // Print commands to Display the result
        System.out.println(
            "Does Groovy language exists in HashMap? "
            + result);
 
        result = languageValueIdentity.get(groovy) != null
                     ? "Yes"
                     : "No";
 
        System.out.println(
            "Does Groovy language in IdenityHashMap? "
            + result);
 
        // Now, modifying the value object
        groovy.setValue(5000);
 
        // Display message only
        System.out.println("After modifying keys  :  ");
 
        // Print commands to Display the result
        result = languageValue.get(groovy) != null ? " Yes "
                                                   : " No ";
 
        System.out.println(
            "Does Groovy language exists in HashMap? "
            + result);
 
        result = languageValueIdentity.get(groovy) != null
                     ? " Yes "
                     : " No ";
 
        System.out.println(
            "Does Groovy language exists in IdenityHashMap? "
            + result);
    }
}



输出
Size of HashMap is : 2
Size of IdentityHashMap is : 4

实现: HashMap 使用 hashCode() 来查找存储桶位置。 IdentityHashMap 不使用 hashCode(),而是使用 System.identityHashCode(object)。

示例 2:

Java

// Java Program to illustrate IdentityHashMap by
// Differenciating between HashMap and IdentityHashMap
 
// Importing input output classes
import java.io.*;
// Importing Map,HashMap and IdentityHashMap classes
// from java.util package
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
 
// Class 1
// Helper Class
class ProgrammingLanguage {
 
    // Member variables of this class
    private String language;
    private Integer value;
 
    // Constructor of this class
    public ProgrammingLanguage(String language,
                               Integer value)
    {
 
        // this keyword refers to current objectc itself
        this.language = language;
        this.value = value;
    }
 
    // Method 1
    public String getlanguage()
    {
 
        // Returning language
        return language;
    }
 
    // Method 2
    public Integer getValue()
    {
 
        // Returning value associated with a language
        return value;
    }
 
    // Method 3
    // Sets a new value for a languauge
    public void setValue(Integer value)
    {
        this.value = value;
    }
 
    // Method 4
    // @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result
            = prime * result
              + ((language == null) ? 0 : value.hashCode());
        result
            = prime * result
              + ((language == null) ? null
                                    : language.hashCode());
        return result;
    }
 
    // Method 5
    // @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ProgrammingLanguage other
            = (ProgrammingLanguage)obj;
        if (value == null) {
            if (other.value != null)
                return false;
        }
        else if (!value.equals(other.value))
            return false;
        if (language == null) {
            if (other.language != null)
                return false;
        }
        else if (!language.equals(other.language))
            return false;
        return true;
    }
}
 
// Class 2
// Main Class
public class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        ProgrammingLanguage groovy
            = new ProgrammingLanguage("Groovy", 1000);
        ProgrammingLanguage scala
            = new ProgrammingLanguage("Scala", 2000);
        ProgrammingLanguage ruby
            = new ProgrammingLanguage("Ruby", 3000);
 
        Map languageValue
            = new HashMap<>();
        Map
            languageValueIdentity = new IdentityHashMap<>();
 
        // Inserting elements to object of HashMap created
        // Custom entries
        languageValue.put(groovy, groovy.getValue());
        languageValue.put(scala, scala.getValue());
        languageValue.put(ruby, ruby.getValue());
 
        // Inserting elements to object of IdenityHashMap
        // created Custom entries
        languageValueIdentity.put(groovy,
                                  groovy.getValue());
        languageValueIdentity.put(scala, scala.getValue());
        languageValueIdentity.put(ruby, ruby.getValue());
 
        // Display message only
        System.out.println("Before modifying keys  :  ");
 
        String result = languageValue.get(groovy) != null
                            ? "Yes"
                            : "No";
 
        // Print commands to Display the result
        System.out.println(
            "Does Groovy language exists in HashMap? "
            + result);
 
        result = languageValueIdentity.get(groovy) != null
                     ? "Yes"
                     : "No";
 
        System.out.println(
            "Does Groovy language in IdenityHashMap? "
            + result);
 
        // Now, modifying the value object
        groovy.setValue(5000);
 
        // Display message only
        System.out.println("After modifying keys  :  ");
 
        // Print commands to Display the result
        result = languageValue.get(groovy) != null ? " Yes "
                                                   : " No ";
 
        System.out.println(
            "Does Groovy language exists in HashMap? "
            + result);
 
        result = languageValueIdentity.get(groovy) != null
                     ? " Yes "
                     : " No ";
 
        System.out.println(
            "Does Groovy language exists in IdenityHashMap? "
            + result);
    }
}
输出
Before modifying keys  :  
Does Groovy language exists in HashMap? Yes
Does Groovy language in IdenityHashMap? Yes
After modifying keys  :  
Does Groovy language exists in HashMap?  No 
Does Groovy language exists in IdenityHashMap?  Yes 

输出说明:

从输出中可以清楚地看出,一旦编程语言 对象被更改,它是 HashMap 和IdentityHashMap 的关键,我们无法在HashMap的情况下检索对象,但在使用IdentityHashMap时可以检索,因为前者使用equals()方法,一旦值更改就返回 false后者使用“==”运算符返回true,因为在这两种情况下,对象在堆中是相同的。