HashSet的基本认识及基本使用
1.此类实现 Set 接口,
2.由哈希表(实际上是一个 HashMap 实例)支持。
3.它不保证 set 的迭代顺序;
4.特别是它不保证该顺序恒久不变。
5.此类允许使用 null 元素。
6注意,此实现不是同步的Set s = Collections.synchronizedSet(new HashSet(...));
注意:HashSet的 基本使用容器类得要一个容器然后使用
HashSet的 特点
1.添加不重复的元素
2.一个容器对象,添加了一种类型还可以添加其他类型
3.可以添加任意类型的数据
ex1:测试添加不重复的元素和可以添加任意类型数据
/**
* HashSet的特点
* 1.添加不重复的元素
* 2.一个容器对象,添加了一种类型还可以添加其他类型
* 3.可以添加任意类型的数据
* @author 郑清
*/
public class Demo {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
hashSet.add(666);//int类型:666
hashSet.add(666);
hashSet.add("666");//String类型:666
hashSet.add("666");
System.out.println(hashSet.size());//2 ==》原因:一个int类型666和一个String类型666
System.out.println(hashSet);
}
}
运行结果图:
ex2:测试HashSet如何判断元素重复
/**
* HashSet判断元素重复的标准
* hashCode值是否相同,及equals结果是否为true
* hashCode相同,并且 equals比较的结果为true,表示元素相同
* @author 郑清
*/
public class Deme {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
hashSet.add(666);//int类型:666
hashSet.add(666);
hashSet.add("666");//String类型:666
hashSet.add("666");
System.out.println(hashSet.size());//2 ==》原因:一个int类型666和一个String类型666
System.out.println(hashSet);//[666, 666]
Integer i1 = 666;
Integer i2 = 666;
//特点:Integer值666,hashCode值也是666
System.out.println(i1.equals(i2));//true
System.out.println(i1.hashCode());//666
System.out.println(i2.hashCode());//666
String str1 = "666";
String str2 = "666";
//特点:字符串一样,Hashcode值一样
System.out.println(str1.equals(str2));//true
System.out.println(str1.hashCode());//53622
System.out.println(str2.hashCode());//53622
Student stu1 = new Student("张三",18);
Student stu2 = new Student("张三",18);
hashSet.add(stu1);
hashSet.add(stu2);
System.out.println(hashSet.size());//4 ==》原因:一个int类型666和一个String类型666 stu1对象地址值和stu2对象地址值分别保存("张三",18)
System.out.println(hashSet);
}
}
/*
* 通过自定义类,覆写equals以及hashCode 验证是否在通过这两条件判断重复
* 真正比较一个元素(对象)否重复,参考字段
* 1.验证equals fasle hashCode 0
* 2.验证equals true hashCode 0
* 3.验证equals true hashCode值不一样
* */
class Student{//hashcode equlas
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
return true;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return new Random().nextInt();
}
@Override
public String toString() {
// TODO Auto-generated method stub
return name+"-->"+age;
}
}
运行结果图:
ex3:覆写自定义类中的hashCode及equals方法
/**
* 1.覆写自定义类中的hashCode及equals方法
* 2.为什么需要覆写:
* ①因为,我们将来自定义的类型,需要创建对象[元素],放入到HashSet容器中
* ②如果直接使用父类的hashCode,equals方法,方法体,是不能满足我们的要求的
* ③因为我们自己写的类,判断对象是否重复,是需要参考自定义类的字段的
* @author 郑清
*/
public class Demo {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
Student stu1 = new Student("张三",18);
Student stu2 = new Student("张三",19);
hashSet.add(stu1);
hashSet.add(stu2);
System.out.println(hashSet.size());
System.out.println(hashSet);
}
}
//通过自定义类,覆写equals以及hashCode 验证是否在通过这两个条件判断重复
//真正比较一个元素(对象)是否重复,参考字段
class Student{//hashcode equlas
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
Student stu = (Student)obj;
return this.name.equals(stu.name)&&this.age == stu.age;
}
//HashCode值也应该参考字段[]
/*
* 此处的HashCode存在问题
* 假设:
* String name = XXX->68 int age = 98
* String name = OOO->98 int age = 68
* */
@Override
public int hashCode() {
return name.hashCode()+age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return name+"---"+age;
}
}
运行结果图:
ex4:使用eclipse系统自带的方法去覆写hashCode和equals方法 ==》
/**
* 1.覆写自定义类中的hashCode及equals方法
* 2.为什么需要覆写:
* ①因为,我们将来自定义的类型,需要创建对象[元素],放入到HashSet容器中
* ②如果直接使用父类的hashCode,equals方法,方法体,是不能满足我们的要求的
* ③因为我们自己写的类,判断对象是否重复,是需要参考自定义类的字段的
* @author 郑清
*/
public class Demo {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
Student stu1 = new Student("张三",18);
Student stu2 = new Student("张三",19);
hashSet.add(stu1);
hashSet.add(stu2);
System.out.println(hashSet.size());//2
System.out.println(hashSet);//[张三-->18, 张三-->19]
Student stu3 = stu2;//将stu2地址值指向stu3
hashSet.add(stu3);
System.out.println(hashSet.size());//2
System.out.println(hashSet);//[张三-->18, 张三-->19]
}
}
//通过自定义类,覆写equals以及hashCode 验证是否在通过这两条件判断重复
//真正比较一个元素(对象)否重复,参考字段
class Student{//hashcode equlas
String name;
int age;
@Override
public int hashCode() {
final int prime = 31;//为了 减少碰撞的可能性:产生的HashCode值如果一样,发生碰撞
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;//还是不错,但是有缺点,但是已经没法改了
}
//stu1.equals(stu2)
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())//比较类型,说明OK
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))//!false
return false;
return true;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return name+"-->"+age;
}
}
运行结果图: