Set-HashSet实现类:算法
遍历一个Set的方法只有一个:迭代器(interator)。数组
HashSet中元素是无序的(这个无序指的是数据的添加顺序和后来的排列顺序不一样),并且元素不可重复。code
在Object中除了有final(),toString(),equals(),还有hashCode()。对象
HashSet底层用的也是数组。接口
当向数组中利用add(Object o)添加对象的时候,系统先找对象的hashCode:string
int hc=o.hashCode(); 返回的hashCode为整数值。hash
Int I=hc%n;(n为数组的长度),取得余数后,利用余数向数组中相应的位置添加数据,以n为6为例,若是I=0则放在数组a[0]位置,若是I=1,则放在数组a[1]位置。若是equals()返回的值为true,则说明数据重复。若是equals()返回的值为false,则再找其余的位置进行比较。这样的机制就致使两个相同的对象有可能重复地添加到数组中,由于他们的hashCode不一样。效率
若是咱们可以使两个相同的对象具备相同hashcode,才能在equals()返回为真。遍历
在实例中,定义student对象时覆盖它的hashcode。迭代器
由于String类是自动覆盖的,因此当比较String类的对象的时候,就不会出现有两个相同的string对象的状况。
如今,在大部分的JDK中,都已经要求覆盖了hashCode。
结论:如将自定义类用hashSet来添加对象,必定要覆盖hashcode()和equals(),覆盖的原则是保证当两个对象hashcode返回相同的整数,并且equals()返回值为True。
若是偷懒,没有设定equals(),就会形成返回hashCode虽然结果相同,但在程序执行的过程当中会屡次地调用equals(),从而影响程序执行的效率。
咱们要保证相同对象的返回的hashCode必定相同,也要保证不相同的对象的hashCode尽量不一样(由于数组的边界性,hashCode仍是可能相同的)。例子:
public int hashCode(){
return name.hashcode()+age;
}
这个例子保证了相同姓名和年龄的记录返回的hashCode是相同的。
使用hashSet的优势:
hashSet的底层是数组,其查询效率很是高。并且在增长和删除的时候因为运用的hashCode的比较开肯定添加元素的位置,因此不存在元素的偏移,因此效率也很是高。由于hashSet查询和删除和增长元素的效率都很是高。
可是hashSet增删的高效率是经过花费大量的空间换来的:由于空间越大,取余数相同的状况就越小。HashSet这种算法会创建许多无用的空间。
使用hashSet接口时要注意,若是发生冲突,就会出现遍历整个数组的状况,这样就使得效率很是的低。
练习:new一个hashset,插入employee对象,不容许重复,而且遍历出来。