ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

哈希表-存储自定义对象

2021-05-10 12:00:58  阅读:143  来源: 互联网

标签:存储 hash Student 自定义 age hashCode 哈希 public name


package en.itcast.demain;

public class Student {//自定义的学生类
	private int age;
	private String name;
	
	public Student() {
		super();
	}

	public Student(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}

	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;
	}
	
	/**
	 * 覆盖hashCode方法。根据对象自身的特点定义哈希值。
	 */
	@Override
	public int hashCode() {
		final int NUMBER = 36;
		return this.name.hashCode() + this.age*NUMBER;
		
		/**
		 * 4.在学生类中定义的hashCode方法中,由于学生年龄相仿的人有许多,会造成多次hash值冲突,导致调用过多的equals方法,
		 * 为此,应该改进hashCode方法。
		 * 可利用String中的hashCode方法输出字符串的哈希值,再加上原来的age,作为返回的hash值,为此,hash值冲突就会减少。
		 * 5.进一步减少hash值冲突,我可以在age后面乘以一个值--->原理:
		 * eg:
		 * name.hashCode() = 40,age = 20;
		 * name.hashCode() = 20,age = 40;
		 * 以上又会造成返回hash值冲突,当给age乘以一个数时,hash值冲突的概率会进一步减少。
		 */
	}
	
	/**
	 * 需要定义对象自身判断内容相同的依据。
	 */
	@Override
	public boolean equals(Object obj) {
		System.out.println(this+"..."+obj);//查看生成对象时是如何调用equals方法
		if(this == obj) {
			return true;
		}
		
		if(!(obj instanceof Student)) {
			throw new ClassCastException("类型错误");
		}
		Student student = (Student)obj;//强转:即所谓的向下转型
		return this.name.equals(student.name)&&this.age == student.age;
		
	}
	

}
package en.itcast.set.demo;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import en.itcast.demain.Student;

public class HashSetTest {//测试类

	public static void main(String[] args) {
		/*
		 * 需求:往HashSet中存储学生对象(姓名,年龄)。同姓名,同年龄视为同一个人,不存。
		 * 1.描述学生
		 * 2.定义容器
		 * 3.将学生存储到容器
		 * 
		 */
		
		//1.创建容器对象
		Set set = new HashSet<>();
		
		//2.将学生存储到容器
		/**
		 * 按照道理说:将同一个对象存入HashSet容器中,由于不允许存入重复元素,输出不会有重复元素
		 * 可输出事与愿违,原因出在何处?
		 * because:因为Student对象继承了Object对象中hashCode方法,使得创建每一个对象是调用hashCode()方法,
		 * 生存了不同的hash值,而容器中add方法是根据hash值来存储对象的,所以虽然是同一个对象,但是对应不同的hash值,
		 * 自然可以存入其中。
		 * 
		 * 解决:
		 * 1.需要根据学生对象自身的特点来定义哈希值。
		 * 所以就要覆盖hashCode方法,我在Studnet类中是依据年龄返回哈希值的,然这不足以区分相同对象,因为同一年龄的对象有很多。
		 * 2.为此,就要利用针对同一个hash值冲突的解决办法,也就是重写equals方法,对每一个对象内容进行判断,至此可达到区分同一个对象的效果
		 * 3.注意:为什么之前存入相同字符串到HashSet容器中存不进去,应为String类有自己的hashCode方法,没有调用Object中hashCode方法,
		 * 自然区分了同一个字符串对应同一个哈希值。
		 * 4.在学生类中定义的hashCode方法中,由于学生年龄相仿的人有许多,会造成多次hash值冲突,导致调用过多的equals方法,
		 * 为此,应该改进hashCode方法。
		 * 可利用String中的hashCode方法输出字符串的哈希值,再加上原来的age,作为返回的hash值,为此,hash值冲突就会减少。
		 * 5.进一步减少hash值冲突,我可以在age后面乘以一个值--->原理:
		 * eg:
		 * name.hashCode() = 40,age = 20;
		 * name.hashCode() = 20,age = 40;
		 * 以上又会造成返回hash值冲突,当给age乘以一个数时,hash值冲突的概率会进一步减少。
		 * 6.利用编译器自动生成
		 */
		set.add(new Student(21, "zhang3"));
		set.add(new Student(22, "li4"));
		set.add(new Student(21, "xurong"));
		set.add(new Student(23, "wang5"));
		set.add(new Student(21, "zhang3"));
		set.add(new Student(22, "li4"));
		
		//3.将其输出
		for (Iterator it = set.iterator();it.hasNext();) {
			Student student = (Student)it.next();
			System.out.println(student.getName()+"::"+student.getAge());
		}
		
	}

}

输出结果:

en.itcast.demain.Student@d6168cbb...en.itcast.demain.Student@d6168cbb
en.itcast.demain.Student@1a56f...en.itcast.demain.Student@1a56f
wang5::23
xurong::21
zhang3::21
li4::22

标签:存储,hash,Student,自定义,age,hashCode,哈希,public,name
来源: https://blog.csdn.net/weixin_45846799/article/details/116591839

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有