hash(散列)?java
散列数据结构,可是java这里屏蔽了,直接就用封装的形式把他封装到了 HashSet,HashMap,HashTable中.其中HashTable已通过时了.算法
hash算法:java中指的hashCode()函数及其重写.数组
目标:给每一个对象生成一个惟一的标示符数据结构
根据对象的特色为每一个对象生成一个惟一hashCode,而后把这个hashCode做为下标,把对象值做为元素值保存到数组中(对象的引用).这个时候这个数组就能够看作关联数组.java中没有关联数组这个概念,单独取了个名叫HashSet.函数
Hash的过程:编码
拿到对象,调用他本身的hash算法(hashCode()方法),生成一个惟一的hash值,而后把这个值保存到数组中,整个过程就是hash.数组,和惟一值,和对象的关系,咱们就叫HashSet;spa
hash算法在java中就是指Object中的hashCode()函数里面的算法,这一个是根据你写的类来本身定义的.对象
hash哈希冲突:多个对象可能生成一个相同的hash值.索引
HashSet为何无序,不可重复?接口
1 生成的hashCode没有必定大小关系,就无所谓顺序
2 每一个对象都必须生成一个惟一的hashCode(多个对象能够生成相同的,可是还要比较值),若是是重复的对象,确定是生成同一个hashCode,而且值也是相同的.这个时候就没有办法惟一性查询出某个数据.因此必须是不可重复的.全部的一切为了数据的惟一标识.
HashSet和HashMap
1 HashSet 是HashMap的一个实现,本质是HashMap.而HashMap的数据结构是一个Hash表.
2 Hash表又叫散列表,其底层是经过hashCode()函数组成的一个数组,每一个数组的元素又是一个单向链表.每一个单项链表都有一个独一无二hash值,就是数组的下标,也意味着每一个单项链表的节点的hash值是相同的.
怎么向Hash表中添加元素.
1) 要添加的时候,HashMap保存的是映射关系,这个映射关系靠什么来维护(Map.Entry(K,V)),是一个接口,那咱们就能够传入各类对象的映射关系.若是生成了重复的hash值怎么办?就会往HashTable,桶位上加一个单向链表单向链表中每一个对象都是一个Entry.
重点:2) 添加过程: 第一步:先调用要存储的映射关系的key对象,而后调用key对象自身的hashCode()方法,生成hash码,向数组中添加元素.若是没有这个hash码,就占用一个数组的空间,保存这个key-value映射对象Entry.若是已经有了这个hash码,就须要执行第二步.
第二步:equals(),把键的值挨个在hash码相同的链表中进行比较,若是返回为true那么就表明该链表中已经有了这个key值,就放弃添加,若是没有则返回false,就执行第三步.
第三步:就把数组中当前保存的那个节点向后移动一位(并非真的移动,只是我取得他内存地址,保存在新加入的那个元素的nextNode中),再把当前的这个映射关系对象Entry保存到数组中.
3) HashSet和Hashmap 初始化容量都是16,默认加载因子都是0.75.
索引数组:在内存空间上是连续的记数也是连续的,整体就是有序的
关联数组:在内存空间上是连续的,记数不是连续的,就是无序的
哈希表:用hashCode()函数进行编码的做为下标的关联数组.
咱们用的hashCode()函数可能会有重复的状况,可是数组又规定不能重复,咱们再用equals()比较另一个外属性(必须包含两个比较,一个比较hashCode,另一个比较另一个属性.)
hashSet:只保存了一个元素.
hashMap:是一个元素里面保存两个对象的映射关系,再把这个映射关系封装成一个对象