hashset的使用
当我们需要存入不重复的数据时就需要用到hashset,而hashset的不重复的秘密就依赖于equals方法和 hashCode方法。
知识引入:什么是哈希表呢?
哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。
hashCode方法作用:
当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。
总结:运用特殊的算法生成一个哈希数用于给存入的元素定存放的位置。
equals方法的作用:
用于判断存入的数据是否与集合中的数据重复。
举个例子当存入的两个不同的数据经过hashCode方法计算后恰巧得到了相同的哈希数,此时就需要比较他们的内容是否相同。
总结:比较内容是否相同
1.给HashSet中存储JavaAPI中提供的类型元素时,不需要重写元素的hashCode和equals方法,因为这两个方法,在JavaAPI的每个类中已经重写完毕,如String类、Integer类等。
public class HashSetDemo {
public static void main(String[] args) {
//创建HashSet对象
HashSet<String> hs = new HashSet<String>();
//给集合中添加自定义对象
hs.add("zhangsan");
hs.add("lisi");
hs.add("wangwu");
hs.add("zhangsan");
//取出集合中的每个元素
Iterator<String> it = hs.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
结果:wangwu
lisi
zhangsan
2.给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一
1.创建自定义对象student,在对象中重写hashCode和equals方法
public class student {
private int age ;
private String name;
@Override
public student(String name, int age) {
super();
this.name=name;
this.age=age;
}
public String toString() {
return "student [age=" + age + ", name=" + name + "]";
}
public void setage(int age) {
this.age=age;
}
public int getage() {
return age;
}
public void stename(String name) {
this.name=name;
}
public String getname() {
return name;
}
@Override
public int hashCode() {//重写hashCode()方法
final int prime = 31;
int result = 1;
result = prime * result + age;//int类型数据用此计算方法----其他方法见链接
result = prime * result + ((name == null) ? 0 : name.hashCode());//String类型数据用此计算方法
return result;//有同学肯定会疑惑为什么写了两个result,原因很简单用当我们自己写自定义类时肯定会有多个数据类,如本例就有age,name。那么第一个result通过age获得一个值,在后面在第一个result的基础上通过name又获取了一个新的result指这样两步下来得到的哈希数值就更大可能的不会重复。
}
@Override
public boolean equals(Object obj) {//重写 equals()方法---根据自己的数据需求编写方法
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
student other = (student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;//当集合中没有名字而添加的元素有名字时返回false
} else if (!name.equals(other.name))//当集合中有名字元素时比较加入的元素名看是否相同不同返回false
return false;
return true;
}
}
2.创建HashSet集合,存储student对象。
import java.util.HashSet;
import java.util.Iterator;
public class testdemo {
public static void main(String[] args) {
HashSet<student> set=new HashSet<student>();
set.add(new student("yueshuai",22));
set.add(new student("yueshuai",22));
set.add(new student("xiaoma",22));
set.add(new student("xiaozhou",23));
Iterator<student> k=set.iterator();//迭代器
while(k.hasNext()) {
student f=k.next();
System.out.println(f);
}
}
}
结果: student [age=22, name=xiaoma]
student [age=23, name=xiaozhou]
student [age=22, name=yueshuai]
由结果可见hashset方法存入的数据是没有顺序的。
链接:
hashcode通用计算公式
学习心得:
当需要存入不重复的数据时可以用hashset,但是存入数据是没有顺序的,想要有序可以使用LinkedHashSet。
同时使用它时还需要重写hashcode 和equals方法,当熟练后可以用自动生成方式。
鼠标右键找到如下图所示