Java语言学习day38--8月13日
###11哈希表的数据结构
A:哈希表的数据结构:(参见图解)
加载因子:表中填入的记录数/哈希表的长度
例如:
加载因子是0.75 代表:
数组中的16个位置,其中存入16*0.75=12个元素
如果在存入第十三个(>12)元素,导致存储链子过长,会降低哈希表的性能,那么此时会扩充哈希表(在哈希),底层会开辟一个长度为原长度2倍的数组,把老元素拷贝到新数组中,再把新元素添加数组中
当存入元素数量>哈希表长度*加载因子,就要扩容,因此加载因子决定扩容时机
###12字符串对象的哈希值
A:字符串对象的哈希值
/*
* 对象的哈希值,普通的十进制整数
* 父类Object,方法 public int hashCode() 计算结果int整数
*/
public class HashDemo {
public static void main(String[] args) {
Person p = new Person();
int i = p.hashCode();
System.out.println(i);
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
/*System.out.println("重地".hashCode());
System.out.println("通话".hashCode());*/
}
}
//String类重写hashCode()方法
//字符串都会存储在底层的value数组中{'a','b','c'}
public int hashCode() {
int h = hash;//hash初值为0
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
###13哈希表的存储过程
A:哈希表的存储过程
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
set.add(new String("abc"));
set.add(new String("abc"));
set.add(new String("bbc"));
set.add(new String("bbc"));
System.out.println(set);
}
存取原理:
每存入一个新的元素都要走以下三步:
1.首先调用本类的hashCode()方法算出哈希值
2.在容器中找是否与新元素哈希值相同的老元素,
如果没有直接存入
如果有转到第三步
3.新元素会与该索引位置下的老元素利用equals方法一一对比
一旦新元素.equals(老元素)返回true,停止对比,说明重复,不再存入
如果与该索引位置下的老元素都通过equals方法对比返回false,说明没有重复,存入
###14哈希表的存储自定义对象
A:哈希表的存储自定义对象
/*
* HashSet集合的自身特点:
* 底层数据结构,哈希表
* 存储,取出都比较快
* 线程不安全,运行速度快
*/
public class HashSetDemo1 {
public static void main(String[] args) {
//将Person对象中的姓名,年龄,相同数据,看作同一个对象
//判断对象是否重复,依赖对象自己的方法 hashCode,equals
HashSet<Person> setPerson = new HashSet<Person>();
setPerson.add(new Person("a",11));
setPerson.add(new Person("b",10));
setPerson.add(new Person("b",10));
setPerson.add(new Person("c",25));
setPerson.add(new Person("d",19));
setPerson.add(new Person("e",17));//每个对象的地址值都不同,调用Obejct类的hashCode方法返回不同哈希值,直接存入
System.out.println(setPerson);
}
}
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person(){}
public String toString(){
return name+".."+age;
}
}
###15自定义对象重写hashCode和equals
A:自定义对象重写hashCode和equals
/*
* HashSet集合的自身特点:
* 底层数据结构,哈希表
* 存储,取出都比较快
* 线程不安全,运行速度快
*/
public class HashSetDemo1 {
public static void main(String[] args) {
//将Person对象中的姓名,年龄,相同数据,看作同一个对象
//判断对象是否重复,依赖对象自己的方法 hashCode,equals
HashSet<Person> setPerson = new HashSet<Person>();
setPerson.add(new Person("a",11));
setPerson.add(new Person("b",10));
setPerson.add(new Person("b",10));
setPerson.add(new Person("c",25));
setPerson.add(new Person("d",19));
setPerson.add(new Person("e",17));
System.out.println(setPerson);
}
}
public class Person {
private String name;
private int age;
/*
* 没有做重写父类,每次运行结果都是不同整数
* 如果子类重写父类的方法,哈希值,自定义的
* 存储到HashSet集合的依据
*
* 尽可能让不同的属性值产生不同的哈希值,这样就不用再调用equals方法去比较属性
*
*/
public int hashCode(){
return name.hashCode()+age*55;
}
//方法equals重写父类,保证和父类相同
//public boolean equals(Object obj){}
public boolean equals(Object obj){
if(this == obj)
return true;
if(obj == null)
return false;
if(obj instanceof Person){
Person p = (Person)obj;
return name.equals(p.name) && age==p.age;
}
return false;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person(){}
public String toString(){
return name+".."+age;
}
}
###16LinkedHashSet集合
A:LinkedHashSet集合
/*
* LinkedHashSet 基于链表的哈希表实现
* 继承自HashSet
*
* LinkedHashSet 自身特性,具有顺序,存储和取出的顺序相同的
* 线程不安全的集合,运行速度块
*/
public class LinkedHashSetDemo {
public static void main(String[] args) {
LinkedHashSet<Integer> link = new LinkedHashSet<Integer>();
link.add(123);
link.add(44);
link.add(33);
link.add(33);
link.add(66);
link.add(11);
System.out.println(link);
}
}
###17ArrayList,HashSet判断对象是否重复的原因
A:ArrayList,HashSet判断对象是否重复的原因
a:ArrayList的contains方法原理:底层依赖于equals方法
ArrayList的contains方法会使用调用方法时,
传入的元素的equals方法依次与集合中的旧元素所比较,
从而根据返回的布尔值判断是否有重复元素。
此时,当ArrayList存放自定义类型时,由于自定义类型在未重写equals方法前,
判断是否重复的依据是地址值,所以如果想根据内容判断是否为重复元素,需要重写元素的equals方法。
b:HashSet的add()方法和contains方法()底层都依赖 hashCode()方法与equals方法()
Set集合不能存放重复元素,其添加方法在添加时会判断是否有重复元素,有重复不添加,没重复则添加。
HashSet集合由于是无序的,其判断唯一的依据是元素类型的hashCode与equals方法的返回结果。规则如下:
先判断新元素与集合内已经有的旧元素的HashCode值
如果不同,说明是不同元素,添加到集合。
如果相同,再判断equals比较结果。返回true则相同元素;返回false则不同元素,添加到集合。
所以,使用HashSet存储自定义类型,如果没有重写该类的hashCode与equals方法,则判断重复时,使用的是地址值,如果想通过内容比较元素是否相同,需要重写该元素类的hashcode与equals方法。
Java语言学习day38--8月13日的更多相关文章
- Python学习日志9月13日
昨天的学习日志没有写,乱忙了一整天,政治电脑. 好奇心重,想要给电脑装上传说中LInux操作系统,各种小问题折腾到半夜,今天又折腾到晚上才真正的装上系统. 可是装上系统后又发现各种的不好用.虽然界面比 ...
- python学习 day08 (3月13日)----函数
函数 一.定义 def 关键字 函数名(): 函数体 函数 ---- 封装#def 关键字 # #定义后的函数就像变量 不调用是不执行的 # #函数名() ==函数的调用 def code(): ...
- Java语言学习day01--6月28日
Java语言学习day01一:Java概述 1.Java语言发展史 任职于太阳微系统的 詹姆斯·高斯林 等人于1990年代初开发Java语言的雏形,最初被命名为 Oak ,目标设置在 家用电器等小型系 ...
- Java语言学习day02--6月29日
Java语言学习day02###01常用的DOS命令 * A: 常用的DOS命令 * a: 打开Dos控制台 * win+r--cmd--回车 * b: 常用dos命令 * cd.. : 退回到上一级 ...
- 09.13日记(2014年9月13日00:18:26)英语,bootstrap,阮一峰,
我们这里只推荐一本语法书:台湾的旋元佑老师写的<文法俱乐部>(简体版名为<语法俱乐部>).这本书因为出版社倒闭而绝版,淘宝可以买到影印的版本. (1)学英语:奶爸的英语教室 资 ...
- Python学习日志9月17日 一周总结
周一,9月11日 这天写的是过去一周的周总结,我从中找出当天的内容. 这天早晨给电脑折腾装机,早晨基本上没有学习,休息了一个早晨. 下午写的上周总结,完事做mooc爬虫课的作业,<Think P ...
- JavaScript图表FusionCharts免费在线公开课,由印度原厂技术工程师主讲,10月13日发车
FusionCharts公开课达人还你做 轻松晋升图表大师 [开课时间]10月13日 14:30[主讲老师]印度原厂技术工程师[开课形式]网络在线公开课[活动费用]前50名免费 现在就可以报名哦 报 ...
- [转载]Ubuntu17.04(Zesty Zapus)路线图发布:2017年4月13日发布
Canonical今天公布了Ubuntu 17.04(Zesty Zapus)操作系统的发布路线图,该版本于今年10月24日上线启动,toolchain已经上传且首个daily ISO镜像已经生成.面 ...
- 2015年12月13日 spring初级知识讲解(四)面向切面的Spring
2015年12月13日 具体内容待补充...
- 2016年12月13日 星期二 --出埃及记 Exodus 21:8
2016年12月13日 星期二 --出埃及记 Exodus 21:8 If she does not please the master who has selected her for himsel ...
随机推荐
- python神器 Jupyter Notbook
python神器 Jupyter Notbook 简介 Jupyter Notebook是基于网页的用于交互计算的应用程序.其可被应用于全过程计算:开发.文档编写.运行代码和展示结果. Jupyter ...
- 解决HTML中文乱码问题
将HTML代码复制到一个新建的记事本 然后在记事本里面的操作 另存为 选择utf-8编码 新的那个html文本打开 中文已显示正常
- 数据库篇:mysql锁详解
前言 sql事务的执行,如果需要锁定数据进行更新操作,则必定离不开锁 共享锁和排他锁 表锁 行锁 Record Lock 间隙锁 Gap Lock 行锁+间隙锁 Next-Key Lock 加锁场景( ...
- XML 文档定义有几种形式?它们之间有何本质区别?解析 XML 文档有哪几种方式?
XML 文档定义分为 DTD 和 Schema 两种形式,二者都是对 XML 语法的约束,其 本质区别在于 Schema 本身也是一个 XML 文件,可以被 XML 解析器解析,而且 可以为 XML ...
- mybatis插件机制原理
mybatis插件机制及分页插件原理 参考链接:mybatis插件机制及分页插件原理 如何编写一个自定义mybatis插件 参考链接:mybatis 自定义插件的使用
- 是否可以继承 String 类?
String 类是 final 类,不可以被继承. 补充:继承 String 本身就是一个错误的行为,对 String 类型最好的重用方式是关 联关系(Has-A)和依赖关系(Use-A)而不是继承关 ...
- DRF(Django REST Framework)框架
目录 一.DRF中的Request 二.前戏: 关于面向对象的继承 三.初级版本 1. settings.py文件 -- 注册app 2. models.py文件 -- 创建表 3. admin.py ...
- mybatis-02-mapper生成器插件使用
sb_mybatis <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...
- C++中类所占的内存大小以及成员函数的存储位置
类所占内存的大小是由成员变量(静态变量除外)决定的,虚函数指针和虚基类指针也属于数据部分,成员函数是不计算在内的.因为在编译器处理后,成员变量和成员函数是分离的.成员函数还是以一般的函数一样的存在.a ...
- 6_稳定性_李雅普诺夫_Lyapunov
李雅普诺夫方法参考