底层基于hashmap实现,构造函数中会new一个HashMap实例,hashset中的元素都放在hashmap中,key是元素本身,value为PRESENT,PRESENT定义:private static final object PRESENT = new Object(),允许null值,不允许重复。Hashset的add方法其实调用的是hashmap的put方法。Hashmap如果有重复的key,则新的value会覆盖旧的value,所以本质上是没有重复的key。Hashset调用add(object)方法时,会看hashMap的put方法返回值是否为null,如果为null,说明添加成功。如果put方法返回值不是null,说明调用Hashmap的put方法有返回值,该返回值就是oldValue。此时,就不能重复添加了。
Hashset的add过程:遍历table中的元素,如果没有元素与传入对象的hash码值相同,说明传入对象是个新元素,存。
如果有元素与传入对象的hash码值相同,且equals判断相等,说明元素已经存在,不存。
如果有元素与传入对象的hash码值相同,且equals判断不相等,说明元素不存在,存。
所以Hashset存储对象时,先判断的是hashcode(),然后判断的是equals()。如果需要把某个类的对象保存到Hashset的集合中,而且想要保证唯一性,那么重写这个类的hashcode方法和equals方法时,应该尽量保证两个对象通过equals返回true时,它们的hashcode返回值也是相等的。如果该类的equals方法返回true(比如person类,如果age和name相等,equals就返回true)而hashcode返回值不相等,那么hashset依然可以把两个相同name,相同age的人加入到hashset中,这就不符合我们用hashset存储的预期结果了。
Hashset不是线程安全的,Set类想要获取其中的元素只能用Iterator方式。
Iterator itr = set.iterator()…注意itr.next()方法,只是获取该元素,并没有取出该元素。
TreeSet的特点是可以对其中的元素进行排序。换句话说,一种情况是放进treeset中的元素必须具有比较性,集合的底层结构是二叉树,保证元素唯一性的方法是compareTo方法返回0。另一个情况是元素没有比较性,但是集合有比较性,定义一个类,实现Comparator接口,实现一个比较器。
Hashset的构造函数可以传入任何Collection的子类。
标签:Hashset,元素,equals,HashSet,hashset,返回值,解析,方法,底层 From: https://www.cnblogs.com/MarkLeeBYR/p/17111841.html