Java 8如何帮助提高HashMap的性能

Java 8如何帮助提高HashMap的性能

这里我们将讨论如何在Java中使用HashMap时提高性能,_hashCode()契约的重要性,为什么拥有一个高效的哈希码非常重要,以及当我们使用一个低效的哈希码时会发生什么。让我们直接辗转到在我们的HashMap中实现同样的超过相同大小的键集合。具体情况如下。

实现情况: 这里没有引入这样的概念,所以在我们的HashMap上应用的是一种Native方法。

示例 1:

// Java Program to Illustrate In-efficient Technique
// While using HashMap
  
// Importing Map and HashMap utility classes
// from java.util package
import java.util.HashMap;
import java.util.Map;
  
// Main class
class HashMapEx2 {
  
    // main driver method
    public static void main(String[] args)
    {
        // Creating a Map object
        // Declaring object of user-defined class and string
        // type
        Map<Student, String> studentMap = new HashMap<>();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            studentMap.put(new Student("saty" + i),
                           "satyy" + i);
        }
        studentMap.forEach(
            (k, v) -> System.out.println(k + " : " + v));
        long endTime = System.currentTimeMillis();
        long timeElapsed = endTime - startTime;
        System.out.println(
            "\n Execution time in milliseconds for In-Efficient hashcode :  "
            + timeElapsed + " milliseconds.");
    }
}
  
/*Student class.*/
class Student {
    String name;
  
    public Student(String name)
    {
        super();
        this.name = name;
    }
  
    @Override public String toString()
    {
        return "Student [name=" + name + "]";
    }
  
    /* Very in-efficient hashcode override */
    @Override public int hashCode()
    {
        return 12; /* Very inefficient hashcode, returns 12
                      for every key, that means all the keys 
                      will end up in the same bucket */
    }
  
    @Override public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student)obj;
        if (name == null) {
            if (other.name != null)
                return false;
        }
        else if (!name.equals(other.name))
            return false;
        return true;
    }
}

输出: 它包含了大量的输出行,以说明所花费的毫秒,因此,输出卷的最后一个快照被附在下面,以便计算出所有操作所花费的时间。情况如下。

Java 8如何帮助提高HashMap的性能?

输出解释: 在上面的程序中,我们使用Student作为HashMap的键,Student类中的hashCode()重写写得非常低效,对每个Student对象都返回相同的hashcode。

为什么一个高效的哈希码如此重要?

当你运行上述程序时,幕后实际发生的情况是,当HashMap被创建时,它将所有10000个学生对象的键存储到同一个桶中。结果,所有的键都被存储在一个桶里,这导致了巨大的性能冲击,你可以看到第一个程序的执行时间大约是1700毫秒。

现在,在下面的程序中,我们在学生类中的哈希码覆盖是高效的,为每个学生对象返回唯一的哈希码。因此,每个哈希图的键被存储在一个单独的桶中,这使存储键的性能提高了’n’倍,你可以看到第二个程序的执行时间只有大约300毫秒

示例 2:

// Java Program to Illustrate In-efficient Technique
// While using HashMap
  
// Importing Map and HashMap utility classes
// from java.util package
import java.util.HashMap;
import java.util.Map;
  
// Main class
class HashMapEx3 {
  
    // main driver method
    public static void main(String[] args)
    {
        Map<Student, String> studentMap = new HashMap<>();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            studentMap.put(new Student("saty" + i),
                           "satyy" + i);
        }
        studentMap.forEach(
            (k, v) -> System.out.println(k + " : " + v));
        long endTime = System.currentTimeMillis();
        long timeElapsed = endTime - startTime;
        System.out.println(
            "\n Execution time in milliseconds for Efficient hashCode: "
            + timeElapsed + " milliseconds");
    }
}
  
/*Student class.*/
class Student {
    String name;
    public Student(String name)
    {
        super();
        this.name = name;
    }
  
    @Override public String toString()
    {
        return "Student [name=" + name + "]";
    }
  
    /* Efficient hashcode override */
    @Override public int hashCode()
    {
        return name.hashCode()
            * 12; /* Efficient hashcode, returns unique
                hashcode for every key, that
                means the keys will be distributed into
                unique buckets */
    }
  
    @Override public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student)obj;
        if (name == null) {
            if (other.name != null)
                return false;
        }
        else if (!name.equals(other.name))
            return false;
        return true;
    }
}

输出: 它包含了大量的输出行,以说明所花费的毫秒,因此,输出卷的最后一个快照被附在下面,以便计算出所有操作所花费的时间。其内容如下。

Java 8如何帮助提高HashMap的性能?

我们可以发现一个明显的变化,例子1需要接近1700毫秒的时间,而在这里,从输出中可以看出,它只需要接近180秒。因此,当我们比较上述的例子时,10倍的乘数是合理的。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程