因为你没有重写hashCode方法
HashSet集合的主要特点是:不保证顺序(若用LinkedHashSet可以做到按添加时的顺序),因为底层是用Map来实现,唯一性:1.hashCode、equals
元素被添加到 HashSet集合的过程:
首先被添加对象调用该对象的hashCode方法获得hashCode,根据该hashCode寻找HashSet集合所在的内存单元,若两个不同的对象具有相同的hashCode则会调用
equals方法进一步进行比较,具体的比较方式可以自己去实现,默认的比较的是两个对象的引用,若引用相同则不会被添加到集合中,一般我们会自己重写hashCode方法和equlas方法来避免重复添加的问题,因为hashCode的默认计算方式是根据对象的内存地址信息来计算出的,是一个native方法。
若没有hash冲突则该对象就直接被添加到集合当中了,不会再调用equlas。
值得注意的是若某个类依据其某个或某些Filed重写了hashCode方法,在该对象被添加到集合中之后,若修改了该对象参与计算hashCode值得字段,则该对象将不能够再通过
集合的public boolean remove(Object o)方法从集合当中移除了,因为HashSet集合(这种数据结构)就是依靠计算元素的hashCode值来在集合所开辟的那段内存单元中查找、定位到存放元素的位置的,若出现这种情况就发生内存泄露,应该特别注意。 |