1. HashTable简介
Map<K,V>下的集合,存储双值
key是不重复,且key和value不允许为null,元素的存储位置由key决定
通过key去寻找key-value的位置
HashTable是线程安全的。
HashTable的特点
-
继承父类
extends Dictionary<K,V>
hashMap 父类 extends AbstractMap<K,V>
这两个父类都是为key-value结构的集合准备的,但是Dictionary方法单一不够全面,所以Dictionary已经逐渐被弃用 -
实现类
implements Map<K,V>, Cloneable, Serializable
Map<K,V>:以key - value的形式存储数据,并且key是不重复的,元素的存储位置由key决定。也就是可以通过key去寻找key - value的位置,从而得打value的值,适合做查找工作。
Cloneable:集合可以使用clone方法
Serializable:序列化,表示HashMap可以进行可序列化操作 -
内部类
static class Entry<K,V> implements Map.Entry<K,V>
可以存储key - value具体数值
class Enumerator implements Enumeration, Iterator
Iterator 从前向后遍历元素
Enumeration
类似于Iterator,用枚举的方式来遍历集合中的数据,从前往后。古老的方式,不支持快速失败机制
通过Enumerator对hashMap进行遍历,只能单独得到keys和elements,不能获得entrySet
2. HashTable的基本使用
- 定义
Hashtable<Integer,String> hashtable = new Hashtable<>();
Hashtable hashtable1 = new Hashtable<>();
- 添加
//添加
hashtable.put(2,"liuneng");
//不能存储null
// hashtable.put(null,"fsf");
// hashtable.put(5,null);
- 删除
hashtable.remove(2);
- 修改
hashtable.replace(3,"mnmn");
- 查询
//查出key对应的值
System.out.println(hashtable.get(3));
3. HashTable的遍历
- 迭代器遍历
通过entrySet,获得HashTable的“键值对”的Set集合
//entrySet迭代器遍历
Iterator<Map.Entry<Integer,String>> iterator = hashtable.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<Integer,String> next = iterator.next();
System.out.println("key;"+next.getKey()+" "+"value:"+next.getValue());
}
通过keySet,获得HashTable的“键”的Set集合
Iterator<Integer> iterator1 = hashtable.keySet().iterator();
while(iterator1.hasNext()){
Integer next = iterator1.next();
System.out.println("key;"+ next);
}
通过values,获得HashTable的“值”的集合
Iterator<String> iterator2 = hashtable.values().iterator();
while(iterator2.hasNext()){
String next = iterator2.next();
System.out.println("value:"+next);
}
- Enumerationr遍历
只能遍历keys和elements
//Enumeration遍历 keys
Enumeration<Integer> enumeration = hashtable.keys();
while (enumeration.hasMoreElements()){
Integer next = enumeration.nextElement();
System.out.println("key;"+ next);
}
System.out.println("----------------------------");
//element
Enumeration<String> enumeration1 = hashtable.elements();
while (enumeration1.hasMoreElements()){
String next = enumeration1.nextElement();
System.out.println("value:"+next);
}
4. WeakHashTable简介
WeakHashMap继承AbstractMap,实现了Map<K,V>接口。使用方法、基本特点、底层数据结构与HashMap相同。
WeakHashMap的键是“弱键”,在WeakHashMap中,如果某个键不再正常使用时,会被从WeakHashMap中自动移除掉。
“弱键”的原理:弱引用,通过WeakReference和ReferenceQueue实现。WeakHashMap中的key是“弱键”,既是WeakReference类型的。ReferenceQueue是一个队列,它会保存被GC回收的“弱键”。
WeakHashTable的特点
implements Map<K,V>
WeakHashMap只实现了Map接口,没有实现clone接口和Serizaseable
当key为null时,使用Object对象替换null,因此key实际存储的是new Object();但打印的时候还是null。
为什么用Obejct替换null?
因为WeakHashMap存储的都是弱引用,当key为null就会被GC回收掉。
WeakHashMap对象存储的都是弱引用,key为“弱键”,当key为null时,GC时,存储的内容将就会被回收掉,如果key - vlaue中有强引用就不会被回收。
4. WeakHashTable代码
当对象无用时,将会被垃圾机制回收掉。
public class weakHashMapTest {
public static void main(String[] args) {
HashMap<String,String> weakHashMap = new HashMap<>();
String s1 = new String("s1");
weakHashMap.put(s1,"to");
weakHashMap.put("s2","qiang");
//底层处理时会用Object对象替换掉null,但打印的时候还是null
weakHashMap.put(null,"null");
Iterator<Map.Entry<String,String>> iterator = weakHashMap.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String,String> next = iterator.next();
System.out.println("key:"+next.getKey()+" value:"+next.getValue());
}
//需要将强引用置null,GC才会回收掉,如果是HashMap s1还在
s1 = null;
//手动调用GC
System.gc();
System.out.println("-------------");
Iterator<Map.Entry<String,String>> iterator1 = weakHashMap.entrySet().iterator();
while (iterator1.hasNext()){
Map.Entry<String,String> next = iterator1.next();
System.out.println("key:"+next.getKey()+" value:"+next.getValue());
}
}
}
结果:
WeakHashMap为弱引用,s1为null就会被回收掉。s2为强引用不能被回收掉。