Set集合相较list集合具有无序,存储元素不可重复的特点.
这里简单记录下Set集合中HashSet在使用时需要主要的几点事项
1.HashSet集合底层使用的是哈希表数据结构,因此在查找的时候速度会非常快
2.集合中只可以存储对象,而不可以存储基本数据类型
private static void func4() {
HashSet set = new HashSet();
set.add(1);
set.add(2);
System.out.println(set);
Iterator it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next() + "...");
}
}
既然只可以存储对象,那么这里为什么可以存储1这样的基本数据类型呢,这是因为这里对其做了一个自动装箱和自动拆箱的一个动作,
与下边这段代码是一致的效果:
private static void func5() {
HashSet set = new HashSet();
set.add(new Integer(1));
set.add(new Integer(2));
System.out.println(set);
Iterator it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next() + "...");
}
}
3.存储元素的时候需要重新对象实例的hashCode()和equals()方法来确保存储的元素是唯一的
public class Person {
private int age;
private String name;
public Person(String n, int a) {
this.age = a;
this.name = n;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
private static void func3(){
HashSet<Person> people = new HashSet<>();
people.add(new Person("张三", 22));
people.add(new Person("李四", 20));
people.add(new Person("张三", 22));
System.out.println(people);
}
例如上边两段代码执行的结果是people集合中有3个对象而不是2个,因为通过new关键字生成的对象都是一个新的对象,需要在内存中开辟独立地存储空间,具有独立地地址值.那么如何让pepole中只存有2个对象呢,这里就需要重写Person对象的hashCode()和equals()方法.当hashCode值相同,需要通过equals判断具体内容是否相同,当equals返回true时,hashSet集合判定这两个元素是相同元素,因此所以只会存储一个.
其原理简单说就是先判断hashCode值是否相同,只有在hashCode值相同的时候才会去调用equals方法,如果hashCode值不相同是不会去调用equals方法的.
public class Person {
private int age;
private String name;
public Person(String n, int a) {
this.age = a;
this.name = n;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
// System.out.println(this.hashCode());
return name.hashCode() + age * 23;
// return 1;
}
@Override
public boolean equals(Object obj) {
//instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
System.out.println("sssssssss");
if (!(obj instanceof Person)) {
return false;
}
Person p = (Person) obj;
boolean b = this.name.equals(p.name) && this.age == p.age;
return b;
}
}
通过上边的代码即可实现我们去重的效果了,这里还有一个小技巧需要特别注意.
在重写的hashCode()方法中需要在返回值中加一个大于1的随机数,以达到hashCode值不重复的目的.
4.一个hashCode值上是也可以存在多个对象的,而非一个.