• JAVA


     
    Hashcode的作用
      总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set。前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。
           要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?这就是Object.equals方法了。但是,如果每增加一个元素就检查一 次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它 就要调用1000次equals方法。这显然会大大降低效率。
           于是,Java采用了哈希表的原理。哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以 直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了;不相同,也就是发生了Hash key相同导致冲突的情况,那么就在这个Hash key的地方产生一个链表,将所有产生相同hashcode的对象放到这个单链表上去,串在一起。所以这里存在一个冲突解决的问题(很少出现)。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。 
     
    equal && hashcode
    以java.lang.Object来理解,JVM每new一个Object,它都会将这个Object丢到一个Hash哈希表中去,这样的话,下次做Object的比较或者取这个对象的时候,它会根据对象的hashcode再从Hash表中取这个对象。这样做的目的是提高取对象的效率。
    具体过程是这样:
    1.new Object(),JVM根据这个对象的Hashcode值,放入到对应的Hash表对应的Key上,如果不同的对象确产生了相同的hash值,也就是发生了Hash key相同导致冲突的情况,那么就在这个Hash key的地方产生一个链表,将所有产生相同hashcode的对象放到这个单链表上去,串在一起。
    2.比较两个对象的时候,首先根据他们的hashcode去hash表中找他的对象,当两个对象的hashcode相同,那么就是说他们这两个对象放在Hash表中的同一个key上,那么他们一定在这个key上的链表上。那么此时就只能根据Object的equal方法来比较这个对象是否equal。当两个对象的hashcode不同的话,肯定他们不能equal. 
     
     
    两个对象相等必须满足:
    • hashcode相等Hash表中的同一个key上>>equals()返回true这个key上的链表上的同一位置
     
    1、如果两个对象相等,那么它们的hashCode值一定要相等;
    2、如果两个对象的hashCode相等,它们并不一定相等。
     
    改写equals时总是要改写hashCode :
    1. import java.util.*; 
    2.  
    3. class V { 
    4.     int i; 
    5.     public V(int i){ 
    6.         this.i = i; 
    7.     } 
    8.     publicint getI(){ 
    9.         returnthis.i; 
    10.     } 
    11.    //如果不重写,将会产生不同的hashcode,所以可以加进set里面 
    12.     publicint hashCode(){ 
    13.         System.out.println("先执行hashCode()方法的!"); 
    14.         return i; 
    15.    }
    16.     public boolean equals(Object o){ 
    17.         V v =(V) o; 
    18.         System.out.print("hashcode相同的,然后才执行的equals()方法的!"); 
    19.         System.out.println(v.getI()==this.i); 
    20.         return v.getI()==this.i; 
    21.     } 
    22.    
    23. } 
    24.  
    25. publicclassTest{ 
    26.     publicstaticvoid main(String[] args){ 
    27.         HashSetset=newHashSet(); 
    28.         for(int i=0; i<10; i++) 
    29.         set.add(newString("test"));//默认重写hashcode() equals()
    30.                                     //产生相同的hashcode,而且equals返回true所以不加进去; 
    31.         System.out.println(set.size()); 
    32.         set.clear(); 
    33.  
    34.         for(int i =0; i <10; i++){ 
    35.             set.add(new V(1)); 
    36.         } 
    37.         System.out.println(set.size()); 
    38.     } 
    39. }  
     
     
     
     





  • 相关阅读:
    hdu-1116(欧拉回路+并查集)
    hdu-1143(简单dp)
    hdu-1141
    JAVA里面获取map的key和value的方法
    MySQL中Date,DateTime,TimeStamp和Time的比较
    idea中修改git提交代码的用户名
    spring配置多个视图解析
    判断Map集合中是否存在某一个key
    win10家庭版升级为win10专业版
    MyBatis模糊查询的三种拼接方式
  • 原文地址:https://www.cnblogs.com/Doing-what-I-love/p/5530471.html
Copyright © 2020-2023  润新知