Collections.unmodifiableMap
来源:互联网 发布:php集成包 编辑:程序博客网 时间:2024/06/05 20:28
1、场景
某些场景下需要返回不可修改Map,java容器类java.util.Collections提供了static方法unmodifiableMap来提供这个功能:
/** * Returns an unmodifiable view of the specified map. This method * allows modules to provide users with "read-only" access to internal * maps. Query operations on the returned map "read through" * to the specified map, and attempts to modify the returned * map, whether direct or via its collection views, result in an * <tt>UnsupportedOperationException</tt>.<p> * * The returned map will be serializable if the specified map * is serializable. * * @param m the map for which an unmodifiable view is to be returned. * @return an unmodifiable view of the specified map. */ public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {return new UnmodifiableMap<K,V>(m); }java.util.Collections将内部类UnmodifiableMap<K,V>权限实现为private,因此外部不能直接访问,仅能通过提供的方法unmodifiableMap获取并使用。
2、实现
/** * @serial include */ private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {// use serialVersionUID from JDK 1.2.2 for interoperabilityprivate static final long serialVersionUID = -1034234728574286014L;private final Map<? extends K, ? extends V> m;UnmodifiableMap(Map<? extends K, ? extends V> m) { if (m==null) throw new NullPointerException(); this.m = m; }public int size() {return m.size();}public boolean isEmpty() {return m.isEmpty();}public boolean containsKey(Object key) {return m.containsKey(key);}public boolean containsValue(Object val) {return m.containsValue(val);}public V get(Object key) {return m.get(key);}public V put(K key, V value) { throw new UnsupportedOperationException(); }public V remove(Object key) { throw new UnsupportedOperationException(); }public void putAll(Map<? extends K, ? extends V> m) { throw new UnsupportedOperationException(); }public void clear() { throw new UnsupportedOperationException(); }private transient Set<K> keySet = null;private transient Set<Map.Entry<K,V>> entrySet = null;private transient Collection<V> values = null;public Set<K> keySet() { if (keySet==null)keySet = unmodifiableSet(m.keySet()); return keySet;}public Set<Map.Entry<K,V>> entrySet() { if (entrySet==null)entrySet = new UnmodifiableEntrySet<K,V>(m.entrySet()); return entrySet;}public Collection<V> values() { if (values==null)values = unmodifiableCollection(m.values()); return values;}public boolean equals(Object o) {return o == this || m.equals(o);}public int hashCode() {return m.hashCode();} public String toString() {return m.toString();} /** * We need this class in addition to UnmodifiableSet as * Map.Entries themselves permit modification of the backing Map * via their setValue operation. This class is subtle: there are * many possible attacks that must be thwarted. * * @serial include */ static class UnmodifiableEntrySet<K,V> extends UnmodifiableSet<Map.Entry<K,V>> { private static final long serialVersionUID = 7854390611657943733L; UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) { super((Set)s); } public Iterator<Map.Entry<K,V>> iterator() { return new Iterator<Map.Entry<K,V>>() { Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator(); public boolean hasNext() { return i.hasNext(); } public Map.Entry<K,V> next() {return new UnmodifiableEntry<K,V>(i.next()); } public void remove() { throw new UnsupportedOperationException(); } }; } public Object[] toArray() { Object[] a = c.toArray(); for (int i=0; i<a.length; i++) a[i] = new UnmodifiableEntry<K,V>((Map.Entry<K,V>)a[i]); return a; } public <T> T[] toArray(T[] a) { // We don't pass a to c.toArray, to avoid window of // vulnerability wherein an unscrupulous multithreaded client // could get his hands on raw (unwrapped) Entries from c.Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0)); for (int i=0; i<arr.length; i++) arr[i] = new UnmodifiableEntry<K,V>((Map.Entry<K,V>)arr[i]); if (arr.length > a.length) return (T[])arr; System.arraycopy(arr, 0, a, 0, arr.length); if (a.length > arr.length) a[arr.length] = null; return a; } /** * This method is overridden to protect the backing set against * an object with a nefarious equals function that senses * that the equality-candidate is Map.Entry and calls its * setValue method. */ public boolean contains(Object o) { if (!(o instanceof Map.Entry)) return false; return c.contains(new UnmodifiableEntry<K,V>((Map.Entry<K,V>) o)); } /** * The next two methods are overridden to protect against * an unscrupulous List whose contains(Object o) method senses * when o is a Map.Entry, and calls o.setValue. */ public boolean containsAll(Collection<?> coll) { Iterator<?> e = coll.iterator(); while (e.hasNext()) if (!contains(e.next())) // Invokes safe contains() above return false; return true; } public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Set)) return false; Set s = (Set) o; if (s.size() != c.size()) return false; return containsAll(s); // Invokes safe containsAll() above } /** * This "wrapper class" serves two purposes: it prevents * the client from modifying the backing Map, by short-circuiting * the setValue method, and it protects the backing Map against * an ill-behaved Map.Entry that attempts to modify another * Map Entry when asked to perform an equality check. */ private static class UnmodifiableEntry<K,V> implements Map.Entry<K,V> { private Map.Entry<? extends K, ? extends V> e; UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {this.e = e;} public K getKey() {return e.getKey();} public V getValue() {return e.getValue();} public V setValue(V value) { throw new UnsupportedOperationException(); } public int hashCode() {return e.hashCode();} public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Map.Entry)) return false; Map.Entry t = (Map.Entry)o; return eq(e.getKey(), t.getKey()) && eq(e.getValue(), t.getValue()); } public String toString() {return e.toString();} } } }其中,访问涉及修改的部分直接抛出异常:
public V put(K key, V value) { throw new UnsupportedOperationException(); }public V remove(Object key) { throw new UnsupportedOperationException(); }public void putAll(Map<? extends K, ? extends V> m) { throw new UnsupportedOperationException(); }public void clear() { throw new UnsupportedOperationException(); }
阅读全文
0 0
- Collections.unmodifiableMap
- Collections.unmodifiableMap
- Collections.unmodifiableMap 用法解析
- Collections.unmodifiableMap()的理解
- Java-Collections.unmodifiableMap()方法
- Collections.unmodifiableMap()分析
- Collections.unmodifiableMap()的简单解释
- 关于Collections.unmodifiableMap的一些理解
- java.util.Collections.unmodifiableMap()方法实例
- 关于collections.unmodifiablemap 的一点理解
- 升级hbase-client报错 java.lang.NoClassDefFoundError: org/apache/commons/collections/map/UnmodifiableMap
- Collections
- Collections
- Collections
- collections
- Collections
- COLLECTIONS
- Collections
- 如何生成微信二维码并将自己的信息存放到二维码中
- (OK) MPTCP-0.92 setup
- 反向(或者后向)插件系统设计
- Android studio初始配置
- hdu 6026 最短路变形+删边构造树的方案数
- Collections.unmodifiableMap
- spring boot spring cloud 打成jar包在Windows或者Linux上运行的几种方式
- 防止js全局变量污染方法总结
- socket编程(十一)
- CentOS7.3安装VMware Tools
- 图解Linux命令之--dd命令
- Apache commons-pool对象池原理分析
- [week 6] [Leetcode] Largest Rectangle in Histogram
- 1208: [HNOI2004]宠物收养所