模仿HashMap写一篇IdentityHashMap的整理。
API截图:
https://blog.fondme.cn/apidoc/jdk-1.8-google/java/util/IdentityHashMap.html
public class IdentityHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, java.io.Serializable, Cloneable { ... }
Constructor and Description |
---|
IdentityHashMap()构造一个带有默认预期最大大小的新的空标识哈希映射(21)。 |
IdentityHashMap(int expectedMaxSize)构造一个具有指定的预期最大大小的新的空白地图。 |
IdentityHashMap(Map<? extends K,? extends V> m)构造一个新的标识哈希映射,其中包含指定地图中的键值映射。 |
1. public IdentityHashMap() { init(DEFAULT_CAPACITY); } 2. public IdentityHashMap(int expectedMaxSize) { if (expectedMaxSize < 0) throw new IllegalArgumentException("expectedMaxSize is negative: " + expectedMaxSize); init(capacity(expectedMaxSize)); } 3. public IdentityHashMap(Map<? extends K, ? extends V> m) { // Allow for a bit of growth this((int) ((1 + m.size()) * 1.1)); putAll(m); }
这个类不是通用的Map实现! 虽然这个类实现了Map接口,但是它有意违反了Map's通用合同,当对比比较时,它要求使用equals方法。 该类仅在需要引用相等语义的罕见情况下才能使用。
我自己使用的特点是啥呢?
方法摘要
public Object clone()
返回此标识哈希映射的浅拷贝:键和值本身不被克隆。
clone
在类别 AbstractMap<K,V>
Cloneable
/** * The initial capacity used by the no-args constructor. * MUST be a power of two. The value 32 corresponds to the * (specified) expected maximum size of 21, given a load factor * of 2/3. */ 哎嗨?初始容量大小32 private static final int DEFAULT_CAPACITY = 32; /** * The minimum capacity, used if a lower value is implicitly specified * by either of the constructors with arguments. The value 4 corresponds * to an expected maximum size of 2, given a load factor of 2/3. * MUST be a power of two. */ private static final int MINIMUM_CAPACITY = 4; /** * The maximum capacity, used if a higher value is implicitly specified * by either of the constructors with arguments. * MUST be a power of two <= 1<<29. * * In fact, the map can hold no more than MAXIMUM_CAPACITY-1 items * because it has to have at least one slot with the key == null * in order to avoid infinite loops in get(), put(), remove() */ 最大容量1<<29 private static final int MAXIMUM_CAPACITY = 1 << 29; Hashmap//最大的容量上限为 2^30 static final int MAXIMUM_CAPACITY = 1 << 30; /** * The table, resized as necessary. Length MUST always be a power of two. */ transient Object[] table; // non-private to simplify nested class access /** * The number of key-value mappings contained in this identity hash map. * * @serial */ int size;
put方法非线程安全的,仅判断了循环结束条件
public V put(K key, V value) { final Object k = maskNull(key); retryAfterResize: for (;;) { final Object[] tab = table; final int len = tab.length; int i = hash(k, len); for (Object item; (item = tab[i]) != null; i = nextKeyIndex(i, len)) { if (item == k) { @SuppressWarnings("unchecked") V oldValue = (V) tab[i + 1]; tab[i + 1] = value; return oldValue; } } final int s = size + 1; // Use optimized form of 3 * s. // Next capacity is len, 2 * current capacity. if (s + (s << 1) > len && resize(len)) continue retryAfterResize; modCount++; tab[i] = k; tab[i + 1] = value; size = s; return null; } }
如何变成线程安全的?
Map m = Collections.synchronizedMap(new IdentityHashMap(...));
把普通的集合转为线程安全的
Collections.synchronizedList()方法,都被同步
我是咋用的?
IdentityHashMap<String, String> subnetequipmentMap = new IdentityHashMap<>(); IdentityHashMap<String, String> subnetSrouterMap = new IdentityHashMap<>(); IdentityHashMap<String, String> subnetserverMap = new IdentityHashMap<>(); IdentityHashMap<String, String> routerFirewallMap = new IdentityHashMap<>(); IdentityHashMap<String, String> routerWsubnetMap = new IdentityHashMap<>(); IdentityHashMap<String, String> dyrouterSubnetMap = new IdentityHashMap<>(); for (Object o : mxCelArr) { JSONObject object = JSON.parseObject(o.toString()); //校验拓扑连线,对象的属性判断 String edge = object.getString("edge"); //线的数组 //线edge if (edge != null) { //断头线 String source = object.getString("source"); String target = object.getString("target"); if (source == null || target == null) { //回环线 } else if (source != null && target != null) { if (!source.equals(target)) { if (subnetIdList.contains(source) && serverIdList.contains(target) || subnetIdList.contains(target) && serverIdList.contains(source)) { subnetserverMap.put(source, target); } if (srouterIdList.contains(source) && firewallIdList.contains(target) || srouterIdList.contains(target) && firewallIdList.contains(source)) { routerFirewallMap.put(source, target); } if (subnetIdList.contains(source) && srouterIdList.contains(target) || subnetIdList.contains(target) && srouterIdList.contains(source)) { subnetSrouterMap.put(source, target); } if (srouterIdList.contains(source) && wsubnetIdList.contains(target) || srouterIdList.contains(target) && wsubnetIdList.contains(source)) { routerWsubnetMap.put(source, target); } if (equipmentIdList.contains(source) && subnetIdList.contains(target) || equipmentIdList.contains(target) && subnetIdList.contains(source)) { subnetequipmentMap.put(source, target); } if (routerIdList.contains(source) && subnetIdList.contains(target) || routerIdList.contains(target) && subnetIdList.contains(source)) { dyrouterSubnetMap.put(source, target); } } } } } map.put("subnetequipmentMap", subnetequipmentMap); map.put("subnetSrouterMap", subnetSrouterMap); map.put("subnetserverMap", subnetserverMap); map.put("routerFirewallMap", routerFirewallMap); map.put("routerWsubnetMap", routerWsubnetMap); map.put("dyrouterSubnetMap", dyrouterSubnetMap); return map; }
本文分享自微信公众号 - 赵KK日常技术记录(gh_cc4c9f1a9521),作者:赵kk
原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。
原始发表时间:2019-10-16
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句