ArrayList和HashSet比较

前言:本博客内容由张孝祥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:5

HashSet size is:3


并没有将teacher1移除,原因请看注释




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值