WeakHashMap,IdentityHashMap,EnumMap

WeakHashMap类实现了Map接口
public class WeakHashMap<K,V>extends AbstractMap<K,V>implements Map<K,V>

与其他Map实现类不同的是,WeakHashMap类的键对象间接地存储为一个弱引用的指示对象,当某个键不再正常使用时,将自动移除其条目。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射中有效地移除。

引用的分类:
1.StrongReference 强引用 ,引用指向对象 ,gc运行时不回收
2.SoftReference 软引用,gc运行时可能会回收,比如当jvm内存不够时,就会回收
3.WeakReference 弱引用,gc运行时立即回收
4.PhantomReference 虚引用,类似于无引用,主要跟踪对象被回收的状态,不能单独使用,必须与引用队列(ReferenceQueue)联合使用

这里主要介绍弱引用:
当调用gc时,gc会回收对象,需要注意的是,它不会回收常量字符串,因为它是放在常量池中被共享的,所以即使断开引用gc也不会删除它,见代码:

import java.lang.ref.WeakReference;

public class Test {
    public static void main(String[] args){
        //字符串常量池
        String str="hello world";
        WeakReference<String> wr=new WeakReference<String>(str);
        //断开引用
        str=null;
        //通知gc回收
        System.gc();
        System.runFinalization();
        System.out.println(wr.get());
    }
}

输出结果是 hello world

import java.lang.ref.WeakReference;
public class Test {
    public static void main(String[] args){
        //String对象
        String str2=new String("hello again");
        WeakReference<String> wr=new WeakReference<String>(str2);
        str2=null;
        System.gc();
        System.runFinalization();
        System.out.println(wr.get());   
    }
}

输出结果是 null

WeakHashMap类

import java.util.WeakHashMap;

public class Test {
    public static void main(String[] args){
        WeakHashMap<String,String> map=new WeakHashMap<String,String>();
        //放入测试数据
        map.put("1", "abc");
        map.put(new String("2"), "qaz");
        System.out.println(map.size());//输出结果为2
        //运行垃圾回收
        System.gc();
        System.runFinalization();
        System.out.println(map.size());//输出结果为1 
    }
}

new String(“2”)这个key值,以及它对应的value值都被删除了 ,所以map.size()为1

WeakHashMap的好处就在这里,如果你HashMap中的数据非常大,占用了大量的内存,你希望在gc运行时可以清理这些内存,就可以用WeakHashMap,而Map其他实现类都不可以实现这一点

IdentityHashMap类
此类利用哈希表实现 Map 接口,比较键(和值)时使用引用相等性代替对象相等性。也就是,在 IdentityHashMap 中,当且仅当 (k1==k2) 时,才认为两个键 k1 和 k2 相等,而在正常 Map 实现类(如 HashMap)中,当且仅当满足下列条件时才认为两个键 k1 和 k2 相等:(k1==null ? k2==null : e1.equals(e2)))。

import java.util.IdentityHashMap;

public class Test {
    public static void main(String[] args){
        IdentityHashMap<String,String> map=new IdentityHashMap<String,String>();
        map.put("a", "qaz");
        map.put("a", "wsx");
        System.out.println(map.size());//输出结果为 1
        map.put(new String("a"), "edc");
        map.put(new String("a"), "rfv");
        System.out.println(map.size());//输出结果为 3


    }
}

这里的字符串常量“a”,是同一块内存地址,所以key相同,而每次new String(“a”),都创建一个新的String对象,开辟新的内存地址,所以是不同的key

EnumMap类
EnumMap要求键值必须是枚举类型,枚举即常量的集合

import java.util.EnumMap;

public class Test {
    public static void main(String[] args){
        EnumMap<Season,String> map=new EnumMap<Season,String>(Season.class);
        map.put(Season.SPRING, "春");
        map.put(Season.SUMMER, "夏");
        map.put(Season.AUTUMN, "秋");
        map.put(Season.WINTER, "冬");

        System.out.println(map.size());//输出结果为4 
    }
}
enum Season{
    SPRING,SUMMER,AUTUMN,WINTER
}

EnumMap的key值不可以是其他的,比如我泛型设置为Integer,是会报错的

你可能感兴趣的:(map,JavaSE)