哈希表结构
哈希表是一种通过关键码去寻找值的映射的数据结构
哈希表就需要通过哈希函数将特定的键映射到特定值的数据结构,维护了键和值之间的对应关系
键:称之为关键字,唯一的表示要存储的数据,也可以是数据本身或者是数据的一部分
哈希函数:将键映射到数据对应存放的位置的函数
哈希冲突:哈希函数将两个不同或者更多的不同的键映射到同一个索引位置
哈希表结构解决两个问题:合理的构建哈希函数,如何解决哈希冲突
哈希函数:
直接寻址法:H(key) = key或者H(key) = a.key+b(a,b为常量)
除留余数法:H(key) = key mod p(p<m,m表示表长)
哈希冲突解决:
链地址法:在冲突的地方通过链表来解决
h(x) = x mod 10
线性探测法:
线性探测:H(i) = i 或者H(i)=i*c(c是常量)
随机探测:H(i) =randon(i)
Map接口:
Map接口是顶层接口,特点是数据以键值对的形式存储
Map接口中提供的方法:
HashMap<String ,String> hashMap = new HashMap<>();
/**
* int size()
* 表示Map集合中元素的个数
* 返回int类型表示数据个数
*/
int size = hashMap.size();
System.out.println(size);
/**
* V put(K key, V value)
* 将指定的键key和value存储到集合中,如果当前插入的数据的key已经存在,最新的value会覆盖原有的value
* 返回值是键值对的值的类型
* map接口下集合特点:key不能重复
* 如果当前key不存在时,插入数据返回为null
* 如果当前key存在时,返回旧的value值
*/
String put = hashMap.put("k1","v1");
System.out.println(put);
String put1 = hashMap.put("k1","v2");
System.out.println(put1);
/**
* V get(Object key)
* 获取键所映射的值,如果不存在则返回为null
*/
String k1 = hashMap.get("k1");
System.out.println(k1);
String k2 = hashMap.get("k2");
System.out.println(k2);
/**
* boolean isEmpty()
* 判断集合是否为空
* 返回时boolean类型,true表示空,false表示不为空
*/
hashMap.isEmpty();
/**
* boolean containsKey(Object key)
* 判断map集合中是否存在指定的键
* 参数key:需要判断是否存在指定的键
* 返回的是Boolean类型
*/
boolean k11 = hashMap.containsKey("k3");
System.out.println(k11);
/**
* boolean containsValue(Object value)
* *判断map集合中是否存在指定的值
*参数:需要判断是否存在指定的值
* 返回的是Boolean类型
*/
boolean v11 = hashMap.containsValue("v1");
System.out.println(v11);
/**
* V remove(Object key)
* 通过key删除集合中该key对应的键值对
* 参数key:指定的键
* 返回值;是value值,如果key不存在返回null
*/
String k12 = hashMap.remove("k1");
/**
* void clear()
* 删除集合中所有的元素
*/
hashMap.clear();
/**
* Set<Map.Entry<K,V>> entrySet()
* 将map集合转化为set集合,多用于遍历键值对
*
*/
Set<Map.Entry<String,String>> entries = hashMap.entrySet();
//map接口按照键值对遍历
Iterator<Map.Entry<String,String>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String,String> entry = iterator.next();
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"<:>"+value);
}
/**
* Set<K> keySet()
* 获取map集合中所有的键的set集合,多用于遍历键
*/
hashMap.keySet();
//遍历map中所有的键
System.out.println("遍历键---");
Iterator<String> iterator1 = hashMap.keySet().iterator();
while (iterator1.hasNext()){
System.out.println(iterator1.next());
}
/**
* Collection<V> values()
* 获取map集合中所有值的collection的集合,多用于值的遍历
*/
hashMap.values();
//遍历map中所有的值
System.out.println("值的遍历------");
Iterator<String> iterator2 = hashMap.values().iterator();
while (iterator2.hasNext()){
System.out.println(iterator2.next());
}
Map集合中实现类遍历的三种方式:
//map接口按照键值对遍历
Iterator<Map.Entry<String,String>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String,String> entry = iterator.next();
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"<:>"+value);
}
//遍历map中所有的键
System.out.println("遍历键---");
Iterator<String> iterator1 = hashMap.keySet().iterator();
while (iterator1.hasNext()){
System.out.println(iterator1.next());
}
//遍历map中所有的值
System.out.println("值的遍历------");
Iterator<String> iterator2 = hashMap.values().iterator();
while (iterator2.hasNext()){
System.out.println(iterator2.next());
}
HashMap
1、HashMap中key不能重复、value值可以重复
2、HashMap中key和value都可以为null
3、不能保证插入的数据的顺序,随着时间的推移,同一个元素的位置可能会发生改变
4、底层采用的数据结构是哈希表结构
通过HashMap源码结构来研究HashMap的原理及特点:
1、继承机构
2、属性及默认值
3、构造函数
4、底层数据结构
5、扩容机制
6、常见方法解析
继承结构:
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
HashMap实现了Map接口
实现了Cloneable接口,并且实现了Serializable接口,能够实现对象的序列化问题
HashMap同时继承自AbstractMap和Map接口,AbstractMap声明如下:
public abstract class AbstractMap<K,V> implements Map<K,V>
对于Map接口中通用的方法做了实现,方便子类字节复用,AbstractMap相当于辅助类,提供了一些操作的默认实现,具体的子类中如果没有特殊行为,可以直接使用AbstractMap提供的实现
属性及默认值:
//map中默认的容量初始值:16 ->2^4
static