/*

* Set:存储的元素是无序的,不可重复的!

*  1.无序性:无序性!= 随机性。真正的无序性,指的是元素在底层存储的位置是无序的(存储时根据hash值随机存储)(add一个元素就调用hashCode()方法算出hsah值  不同的元素算出的hsah值是不相同的并且是没有顺序 根据hash值给元素指定位置,就像同学进教室做座位一样)。

* 2.不可重复性:当向Set中添加进相同的元素的时候,后面的这个不能添加进去。new 出来的对象也不行

 *说明:要求添加进Set中的元素所在的类(自定义类),一定要重写equals()和hashCode()方法。 进而保证Set中元素的不可重复性!(先算hash值 根据hash值指定位置 ,hash值相同再比较equals()方法)

* Set中的元素时如何存储的呢?使用了哈希算法。

* 当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算此对象的哈希值,此哈希值,决定了此对象在Set中的存储位置。若此位置之前没有对象存储,则这个对象直接存储到此位置。若此位置

* 已有对象存储,再通过equals()比较这两个对象是否相同。如果相同,后一个对象就不能再添加进来。 万一返回false呢,都存储。(不建议如此)

* >要求:hashCode()方法要与equals()方法一致,(当两个元素算出同一个hash值时 比较equals(),方法也要为true)

*/

@Test

public void testHashSet() {

Set set = new HashSet();

set.add(123);

set.add(456);

set.add(new String("AA"));

set.add(new String("AA"));  //String重写了两个方法

set.add("BB");

set.add(null); //可以存null

Person p1 = new Person("GG", 23);

Person p2 = new Person("GG", 23);

System.out.println(p1.equals(p2));

System.out.println(p1.hashCode());

System.out.println(p2.hashCode());

set.add(p1);

set.add(p2);

System.out.println(set.size());

System.out.println(set);

}


类中重写

//static int init = 1000;

@Override

public int hashCode() {//return age.hashCode() + name.hashCode();没下述的健壮性好。

final int prime = 31;

int result = 1;

result = prime * result + ((age == null) ? 0 : age.hashCode());

result = prime * result + ((name == null) ? 0 : name.hashCode());

return result;

//return init++;//不能这样用

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Person other = (Person) obj;

if (age == null) {

if (other.age != null)

return false;

} else if (!age.equals(other.age))

return false;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}


/*

* LinkedHashSet:使用链表维护了一个添加进集合中的顺序。导致当我们遍历LinkedHashSet集合

* 元素时,是按照添加进去的顺序遍历的!

* LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

*/

@Test

public void testLinkedHashSet() {

Set set = new LinkedHashSet();

set.add(123);

set.add(456);

set.add(new String("AA"));

set.add(new String("AA"));

set.add("BB");

set.add(null);

f3953d84dd34f70b6c7242d58af83843.png

存入得位置也是无需  根据算出来的hash值存储

Iterator iterator = set.iterator();

while (iterator.hasNext()) {

System.out.println(iterator.next());//链表迭代出来的是按照存入得顺序(因为链表有下标指针,指向下一个元素)

}

}