###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日的更多相关文章

  1. Python学习日志9月13日

    昨天的学习日志没有写,乱忙了一整天,政治电脑. 好奇心重,想要给电脑装上传说中LInux操作系统,各种小问题折腾到半夜,今天又折腾到晚上才真正的装上系统. 可是装上系统后又发现各种的不好用.虽然界面比 ...

  2. python学习 day08 (3月13日)----函数

    函数 一.定义  def  关键字  函数名(): 函数体 函数 ---- 封装#def 关键字 # #定义后的函数就像变量 不调用是不执行的 # #函数名() ==函数的调用 def code(): ...

  3. Java语言学习day01--6月28日

    Java语言学习day01一:Java概述 1.Java语言发展史 任职于太阳微系统的 詹姆斯·高斯林 等人于1990年代初开发Java语言的雏形,最初被命名为 Oak ,目标设置在 家用电器等小型系 ...

  4. Java语言学习day02--6月29日

    Java语言学习day02###01常用的DOS命令 * A: 常用的DOS命令 * a: 打开Dos控制台 * win+r--cmd--回车 * b: 常用dos命令 * cd.. : 退回到上一级 ...

  5. 09.13日记(2014年9月13日00:18:26)英语,bootstrap,阮一峰,

    我们这里只推荐一本语法书:台湾的旋元佑老师写的<文法俱乐部>(简体版名为<语法俱乐部>).这本书因为出版社倒闭而绝版,淘宝可以买到影印的版本. (1)学英语:奶爸的英语教室 资 ...

  6. Python学习日志9月17日 一周总结

    周一,9月11日 这天写的是过去一周的周总结,我从中找出当天的内容. 这天早晨给电脑折腾装机,早晨基本上没有学习,休息了一个早晨. 下午写的上周总结,完事做mooc爬虫课的作业,<Think P ...

  7. JavaScript图表FusionCharts免费在线公开课,由印度原厂技术工程师主讲,10月13日发车

    FusionCharts公开课达人还你做 轻松晋升图表大师 [开课时间]10月13日 14:30[主讲老师]印度原厂技术工程师[开课形式]网络在线公开课[活动费用]前50名免费 现在就可以报名哦  报 ...

  8. [转载]Ubuntu17.04(Zesty Zapus)路线图发布:2017年4月13日发布

    Canonical今天公布了Ubuntu 17.04(Zesty Zapus)操作系统的发布路线图,该版本于今年10月24日上线启动,toolchain已经上传且首个daily ISO镜像已经生成.面 ...

  9. 2015年12月13日 spring初级知识讲解(四)面向切面的Spring

    2015年12月13日 具体内容待补充...

  10. 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 ...

随机推荐

  1. 深度学习工具LabelXml安装教程

    LabelXml安装教程 1,下载LabelXml工具 前往github上下载labelxml,官网地址如下:https://github.com/tzutalin/labelImg 下载打包源码为z ...

  2. java字节流和字符流,以及java文件操作

    A.首先说字节流:1.字节流在操作的时候不会用到缓冲区(也就是内存)2.字节流可用于任何类型的对象,包括二进制对象3.字节流处理单元为1个字节,操作字节和字节数组.InputStream是所有字节输入 ...

  3. synchronized 和 ReentrantLock 的区别?

    synchronized 是和 if.else.for.while 一样的关键字,ReentrantLock 是类, 这是二者的本质区别.既然 ReentrantLock 是类,那么它就提供了比 sy ...

  4. 客户端注册 Watcher 实现?

    1.调用 getData()/getChildren()/exist()三个 API,传入 Watcher 对象 2.标记请求 request,封装 Watcher 到 WatchRegistrati ...

  5. HTML 5中的本地存储概念?

    很多时候,我们想在本地计算机存储有关用户的信息.例如,假设用户已经填满了一半的长表单,互联网却突然连接中断.此时,用户希望能在本地存储这些信息,然后当重新连接到互联网的时候,获取这些信息,并将其发送到 ...

  6. ArrayList、LinkedList、Vector、Array

    ArrayList 本质是一个数组. 优势:追加元素到数组末尾的时候速度快,同时检索元素的速度也快. 劣势:如果要插入一个元素到数组之间慢:如果要追加的元素数量多于数组的容量,则需要频繁扩容使用Arr ...

  7. 常用缓存(cache)淘汰算法(LFU、LRU、ARC、FIFO、MRU)

    缓存算法是指令的一个明细表,用于决定缓存系统中哪些数据应该被删去. 常见类型包括LFU.LRU.ARC.FIFO.MRU. 最不经常使用算法(LFU): 这个缓存算法使用一个计数器来记录条目被访问的频 ...

  8. python模块 | 时间处理模块—datetime模块

    在python中,与时间处理相关的模块有 time,datetime,calendar. 时间的两个概念: UTC(世界协调时): 整个地球分为二十四时区,每个时区都有自己的本地时间.格林威治天文时间 ...

  9. 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)

    概述 最近,有客户向我们请求开发一个前端下拉控件,需求是显示了一个列表,其中包含可由用户单独选择的项目控件,该控件将在下拉列表中显示多选TreeView(树形图). 如今WijmoJS已经实现了该控件 ...

  10. TypeScript中变量调用时后缀感叹号和问号的区别

    typescript编译时,当我们开启严格模式时,下面的代码就会报错: function doSomething(x: string | null) { console.log("Hello ...