/*
* 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);
存入得位置也是无需 根据算出来的hash值存储
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());//链表迭代出来的是按照存入得顺序(因为链表有下标指针,指向下一个元素)
}
}