现在的位置: 首页 > 综合 > 正文

Java漫游-HashSet结构的存取

2018年05月11日 ⁄ 综合 ⁄ 共 2138字 ⁄ 字号 评论关闭

 /*2010 4/12

by Younger.Shen
 
*/
 
Java漫游-HashSet结构的存取
对java的一点点研究,java的庞大自不必说了,无论是复杂的类库还是多样的数据类型,为我们编程自然提供了更多的功能,但是很明显的就是java的多功能是建立在
更加复杂的内部机制中的,这其中的细节部分自然是非常难以掌握,java的核心机制自然很多人都知道,不外乎继承,动态多太,封装,代码复用,以及泛型的相关方面,
但是其中设计的细节就太多了,掌握起来也十分不容易,当然这给我们构造复杂数据类型实现复杂功能的编程提供了很大帮助,研究了很长时间,今天就写一写,备忘,希望
读过的人能给点意见,大家多多交流哈!
 
构造下面的类,下面程序中用最明了的类继承实现了equals方法和hashcode方法的重写,也可以说是覆盖(很多同学分不清楚重写和重载,其实还是很容易区分的,重载大多数
时候是在同一个块中,同一个类或者是其他的块中,而覆盖或者说是重写呢,是在发生继承关系的时候超类方法在子类方法中的重新定义,再次提醒自己这里要多多注意),这里要说明的问题是hash集合的存储的特性以及所使用的技术细节,hashSet之所以速度快是因为数据在它的内部不是按顺序存放的,而是按该数据的哈希值进行索引的,是该数据的哈希值确定了该数据在该结构中的位置,在索引的时候也是使用hash值,HashSet的3大特点就是,其中的数据存放不一定是顺序的,而且其中的顺序有可能在程序的运行过程中发生变化(比如2个相同的数据结构,因为程序操作使其内部的数据成了一样的,而它的哈希值也会变成一样的,这样在操作的时候就会发生意想不到的结果),HashSet是线程不安全的,2个或者2个以上的线程在同时操作HashSet的时候需要人为的来控制线程同步问题,最后是结构内可以存储NULL型引用。
大多数时候我们不太关心上面的问题,真正影响到我们应用的是HashSet本身的特性,hashset中不能放入相同的元素,当一个元素放入结构中的时候,会自动调用该元素的xx.hashcode()方法计算出该元素的哈希值,然后这个值会确定该元素在结构中的位置,在实际的操作过程中,结构会调用元素的equals方法判断是否有和结构中的数据相等,之后判断Hashcode,如果equals返回true,但是2个元素的hashcode不相同的话,那么数据可以成功放入,系统会认为是2个不同的数据元素,
下面的程序中 A和B分别重写了equals方法和hashcode方法,其中A方法的equals始终返回true,B方法的hashcode返回1,这样主方法中在往结构中添加的时候都会没有问题,因为2个A的hashcode不同。2个B的equals返回为false,但是需要注意的是在类C中同时重写了 Hashcode equals方法,这样就会悲剧了,编译完全正常,结果就是只有1个c元素在结构中,在实际应用中如果不注意的话可能需要调试很久才能找到问题所在,这是很严重的。
而且一般情况下如果重写equals方法的话那么也应该重写hashcode方法,就是说如果equals返回true那么hashcode 也应该返回相同的哈希值,这种情况下只能有1个元素被添加,如果equals true 而hashcode不同,那么相同元素会被放到结构中的不同位置中去,但是如果equals false而 hashcode 相同那么会引起更麻烦的问题,其实这里我也不懂怎么回事,调试不出来,希望大家多多交流,
 
Code:
  1. import java.util.*;  
  2.   
  3. class A{  
  4.         public boolean equals(Object o){  
  5.   
  6.         return true;  
  7.     }  
  8.   
  9. }  
  10.   
  11. class B {  
  12.         public  int hashcode(){  
  13.       
  14.             return 1;  
  15.     }  
  16. }  
  17.   
  18. class C{  
  19.   
  20.     public int hashcode(){  
  21.   
  22.         return 2;  
  23.   
  24.     }  
  25.     public boolean equals(Object o){  
  26.   
  27.         return true;  
  28.     }  
  29. }  
  30.   
  31. public class TestHash{  
  32.   
  33.     public static void main(String[] args){  
  34.   
  35.         HashSet books = new HashSet();  
  36.         books.add(new A());  
  37.         books.add(new A());  
  38.         books.add(new B());  
  39.         books.add(new B());  
  40.         books.add(new C());  
  41.         books.add(new C());  
  42.         System.out.println(books);  
  43.     }     
  44. }  
 

抱歉!评论已关闭.