[疯狂Java]集合:IdentityHashMap、EnumMap

翻译 2016年05月31日 21:54:24

1. IdentityHashMap:

    1) 是一种特殊的HashMap,还是用key的hashCode来决定entry的槽位,但是不用key的equals方法来决定是否相等了,而是默认使用地址(即使实现了equals,equals也不起作用)来决定是否相等了!

    2) 所以叫做Identity,就是直接用内存地址严格定义相等;

!!但是IdentityHashMap允许key和value都为null

    3) 示例:

class R {
	int val;

	public R(int val) {
		this.val = val;
	}

	@Override
	public String toString() {
		return "R[val:" + val + "]";
	}

	@Override
	public boolean equals(Object obj) { // equals的标准写法
		if (this == obj) { // 先比较地址
			return true;
		}
		
		if (obj != null && obj.getClass() == R.class) { // 再比较类型(前提是obj不能为空)
			R r = (R)obj; // 先把类型调整一致(当然可以直接return this.val == ((R)obj).val
						  // 但如果在return之前还要用obj进行一些其它复杂操作那用临时的类型转换太麻烦了
			              // 因此先协调类型才是最标准最合理的做法
			return this.val == r.val;
		}
		
		return false; // 地址不同 || obj为空 || 类型不一致,那肯定不一样了!
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return this.val;
	}
	
	
}

public class Test {
	
	public static void main(String[] args) {
		IdentityHashMap map = new IdentityHashMap<>();
		map.put(new R(1), "fun");
		map.put(new R(1), "kun");
		R r = new R(3);
		map.put(r, "xxx");
		map.put(r, "yyy");
		System.out.println(map); // {R[val:1]=fun, R[val:3]=yyy, R[val:1]=kun}
		
		IdentityHashMap map2 = new IdentityHashMap<>();
		map2.put(new String("lala"), "abc");
		map2.put(new String("lala"), "xyz");
		map2.put("mama", "777");
		map2.put("mama", "888");
		System.out.println(map2); // {mama=888, lala=xyz, lala=abc}
	}
}


!!可以发现R的equals不起做用了,而String也实现了equals,同样也不起作用,但是两个"mama"的key没有重复,因为常量字符串是保存在内存常量池中的,因此地址相同;

    4) IdentityHashMap的使用规矩:

         i. 可以看到,它强行把地址的equals当equals方法用了!!

         ii. 而我们之前说过,使用HashMap的原则是equals和hashCode要保持一致,因此我们使用IdentityHashMap的时候就应该让hashCode和地址相等保持一致!!

         iii. 总结:用IdentityHashMap存放的元素最好不重写equals和hashCode(默认从Object继承来的都是直接比较地址,而hashCode返回的就是地址);

!!否则就会像上面的例子一样,equals相等并且hashCode也相等的情况下也出现了元素重复的现象!!这就非常混乱了!!

!!也就是说使用IdentityHashMap保存的元素最好是彻彻底底地根据地址判断是否相等!!!


2. EnumMap:

    1) 和EnumMap类似,只不过要求key必须是枚举类型的值,并且key的枚举类型必须一致(所有元素的key必须都属于同一种枚举类型!),但value的类型随意(Object、String、自定义类型什么的随意);

    2) 构造器:

         i. 不像EnumSet构造时是通过各种静态工具方法构造,EnumMap必须用构造器构造;

         ii. 这里只介绍最常用的版本:EnumMap(Class<K> keyType);  // 用key的类型构造,例如:EnumMap map = new EnumMap(Season.class);

    3) 和EnumSet不允许元素为null一样,EnumMap不允许key为null,但是value无所谓,因为key就代表了entry!但是判空、删除null的方法都能正常使用;

    4) 接下来就可以把EnumMap当成普通Map使用了,可以使用所有Map里有的方法,示例:

enum Season {
	SPRING, SUMMER
}

public class Test {
	public static void main(String[] args) {
		EnumMap map = new EnumMap<>(Season.class);
		map.put(Season.SPRING, "lala");
		map.put(Season.SUMMER, Integer.valueOf(11));
		System.out.println(map);
	}
}
     5) 由于EnumSet、EnumMap都是使用二进制为向量进行映射的(EnumMap映射是通过key映射)的,因此不用担心重复问题,毕竟枚举类型也没有equals、hashCode一说;

相关文章推荐

Java集合之WeakHashMap、IdentityHashMap、EnumMap介绍

WeakHashMapWeakHashMap与HashMap的用法基本类似。区别: HashMap的key保留了对实际对象的强引用,这意味着只要HashMap对象不被销毁,还HashMap的所有key...

Java集合框架之Map--IdentityHashMap,WeakHashMap,EnumMap源码分析

一、IdentityHashMap 该类特点是:     1.只有全等的key值,该类才会认为两个key值相等。比如new String(“11”) 与new String(“11”),这两个对象就...

java学习笔记之WeakHashMap 、IdentityHashMap、EnumMap

WeakHashMap 其中的key是弱引用。(弱引用是指一旦GC运行,就会立刻回收,该引用所指的对象) 例子: “`java /** WeakHashMap 中的key为弱引用,GC...

java-EnumMap、IdentityHashMap、WeakHashMap源码分析

EnumMap源码分析 1、介绍 EnumMap是与枚举类相结合的Map类。跟hash没有多大关系,虽然本文中另外两种与HashMap有关,但是EnumMap与HashMap关系并不大。 Enu...

132_容器_引用(强软弱虚)_WeakHashMap_IdentityHashMap_EnumMap

ReferenceDemo.java package collection.others.Reference;import java.lang.ref.WeakReference;/** * 引用分...

WeakHashMap,IdentityHashMap,EnumMap

WeakHashMap类实现了Map接口 public class WeakHashMapimport java.lang.ref.WeakReference;public class Test {...

java集合IdentityHashMap

IdentityhashMap 中key是对象的引用, 通过判断对引用是否相同,来判断key是否相同, 放入的对象值可以相同,只要两个对象的引用不相同就行了,  如果作为key的引用相同,新放入的...

Java集合框架:EnumMap

EnumMap的key不允许为null,value可以为null,按照key在enum中的顺序进行保存,非线程安全。可以用工具类Collections进行包装成线程安全的: ``` Map m = C...

java集合架构____EnumMap

EnumMap 阅读目录 什么是EnumMap补充说明简单示例 以下内容基于jdk1.7.0_79源码; 什么是EnumMap Map接口的实现,其key-value映射中的key是En...

java集合-EnumMap与EnumSet

一:java枚举简介1:基本概念: 用enum定义枚举类默认继承了java.lang.Enum类而不是继承了Object类。其中java.lang.Enum类实现了java.lang.Serializ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[疯狂Java]集合:IdentityHashMap、EnumMap
举报原因:
原因补充:

(最多只允许输入30个字)