前言:本博客内容由张孝祥Java高新技术整理而来
ListAndHashTest
package com.dao.chu.movie;
import java.util.ArrayList;
import java.util.HashSet;
public class ListAndHashTest {
public static void main(String[] args) {
Teacher teacher1 = new Teacher("张三三", "M", 30);
Teacher teacher2 = new Teacher("李四四", "M", 30);
Teacher teacher3 = new Teacher("王五五", "W", 30);
Teacher teacher4 = new Teacher("张三三", "M", 30);
ArrayList<Teacher> teacherList = new ArrayList<Teacher>();
teacherList.add(teacher1);
teacherList.add(teacher1);
teacherList.add(teacher2);
teacherList.add(teacher3);
teacherList.add(teacher4);
System.out.println("ArrayList size is:"+teacherList.size());
// teacher1和teacher4的hashcode不同,所以分配的区域不同,因此也将teacher4加入了进来
// 为了两个对象的值相同,那么也放在同一区域,我们需要让他们的hashcode也相等
HashSet<Teacher> teachersSet = new HashSet<Teacher>();
teachersSet.add(teacher1);
teachersSet.add(teacher1);
teachersSet.add(teacher2);
teachersSet.add(teacher3);
teachersSet.add(teacher4);
System.out.println("HashSet size is:"+teachersSet.size());
}
}
class Teacher{
private String name;
private String sex;
private int age;
public Teacher(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
输出结果:
ArrayList size is:5
HashSet size is:4
ArrayList会将每一个添加的对象追加在后面,而HashSet在添加对象时,首先判断两个对象是否相等,如果已经有了,就不会添加。
实例中添加了两个teacher1 所以第二个teacher1没有添加进来。
可是teacher1和teacher4的值完全一样,如果我们想当做相等,不添加在HashSet里,要怎么做?我们将Teacher类修改如下:
class Teacher{
private String name;
private String sex;
private int age;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((sex == null) ? 0 : sex.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Teacher other = (Teacher) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex == null) {
if (other.sex != null)
return false;
} else if (!sex.equals(other.sex))
return false;
return true;
}
public Teacher(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
用三个成员变量来计算hashcode这样,teacher1和teacher4的hashcode相等,在同一个区域里面,teacher4就不会添加到HashSet中了。
运行结果:
ArrayList size is:5
HashSet size is:3
和我们期望的一样
注意:当一个对象被存储进了HashSet集合中以后,就不要修改这个对象中那些参与运算哈希值的成员变量了,否则,对象修改后的哈希值和最初存储进HashSet集合中的哈希值就不一致了,会导致无法从HashSet集合中删除当前对象,从而造成内存泄漏。
我们将ListAndHashTest修改如下
public class ListAndHashTest {
public static void main(String[] args) {
Teacher teacher1 = new Teacher("张三三", "M", 30);
Teacher teacher2 = new Teacher("李四四", "M", 30);
Teacher teacher3 = new Teacher("王五五", "W", 30);
Teacher teacher4 = new Teacher("张三三", "M", 30);
ArrayList<Teacher> teacherList = new ArrayList<Teacher>();
teacherList.add(teacher1);
teacherList.add(teacher1);
teacherList.add(teacher2);
teacherList.add(teacher3);
teacherList.add(teacher4);
System.out.println("ArrayList size is:"+teacherList.size());
// teacher1和teacher4的hashcode不同,所以分配的区域不同,因此也将teacher4加入了进来
// 为了两个对象的值相同,那么也放在同一区域,我们需要让他们的hashcode也相等
HashSet<Teacher> teachersSet = new HashSet<Teacher>();
teachersSet.add(teacher1);
teachersSet.add(teacher1);
teachersSet.add(teacher2);
teachersSet.add(teacher3);
teachersSet.add(teacher4);
//反例,修改了成员变量的值
teacher1.setName("修改名字了");
//这句话将不能删除teacher1,因为hashcode改变了,从这个hashcode的区域找不到teacher1从而造成内存溢出
teachersSet.remove(teacher1);
System.out.println("HashSet size is:"+teachersSet.size());
}
}
运行结果:
ArrayList size is:5HashSet size is:3
并没有将teacher1移除,原因请看注释