数据结构之Map
来源:互联网 发布:淘宝女装腔调 编辑:程序博客网 时间:2024/06/06 05:44
直接上JDK源码
Map<K,V>源代码
public interface Map{ int size(); boolean isEmpty(); boolean containsKey(Object key); boolean containsValue(Object value); V get(Object key); V put(K key, V value); V remove(Object key); void putAll(Map extends K, ? extends V> m); void clear(); Set keySet(); Collection values(); Set > entrySet(); interface Entry { K getKey(); V getValue(); V setValue(V value); boolean equals(Object o); int hashCode(); public static , V> Comparator > comparingByKey() { return (Comparator > & Serializable) (c1, c2) -> c1.getKey().compareTo(c2.getKey()); } public static > Comparator > comparingByValue() { return (Comparator > & Serializable) (c1, c2) -> c1.getValue().compareTo(c2.getValue()); } public static Comparator > comparingByKey(Comparator super K> cmp) { Objects.requireNonNull(cmp); return (Comparator > & Serializable) (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey()); } public static Comparator > comparingByValue(Comparator super V> cmp) { Objects.requireNonNull(cmp); return (Comparator > & Serializable) (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue()); } } boolean equals(Object o); int hashCode(); default V getOrDefault(Object key, V defaultValue) { V v; return (((v = get(key)) != null) || containsKey(key)) ? v : defaultValue; } default void forEach(BiConsumer super K, ? super V> action) { Objects.requireNonNull(action); for (Map.Entry entry : entrySet()) { K k; V v; try { k = entry.getKey(); v = entry.getValue(); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } action.accept(k, v); } } default void replaceAll(BiFunction super K, ? super V, ? extends V> function) { Objects.requireNonNull(function); for (Map.Entry entry : entrySet()) { K k; V v; try { k = entry.getKey(); v = entry.getValue(); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } // ise thrown from function is not a cme. v = function.apply(k, v); try { entry.setValue(v); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } } } default V putIfAbsent(K key, V value) { V v = get(key); if (v == null) { v = put(key, value); } return v; } default boolean remove(Object key, Object value) { Object curValue = get(key); if (!Objects.equals(curValue, value) || (curValue == null && !containsKey(key))) { return false; } remove(key); return true; } default boolean replace(K key, V oldValue, V newValue) { Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || (curValue == null && !containsKey(key))) { return false; } put(key, newValue); return true; } default V replace(K key, V value) { V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { curValue = put(key, value); } return curValue; } default V computeIfAbsent(K key, Function super K, ? extends V> mappingFunction) { Objects.requireNonNull(mappingFunction); V v; if ((v = get(key)) == null) { V newValue; if ((newValue = mappingFunction.apply(key)) != null) { put(key, newValue); return newValue; } } return v; } default V computeIfPresent(K key, BiFunction super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue; if ((oldValue = get(key)) != null) { V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) { put(key, newValue); return newValue; } else { remove(key); return null; } } else { return null; } } default V compute(K key, BiFunction super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue = get(key); V newValue = remappingFunction.apply(key, oldValue); if (newValue == null) { // delete mapping if (oldValue != null || containsKey(key)) { // something to remove remove(key); return null; } else { // nothing to do. Leave things as they were. return null; } } else { // add or replace old mapping put(key, newValue); return newValue; } } default V merge(K key, V value, BiFunction super V, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); V oldValue = get(key); V newValue = (oldValue == null) ? value : remappingFunction.apply(oldValue, value); if(newValue == null) { remove(key); } else { put(key, newValue); } return newValue; }}
List的实现类:
Bindings, ConcurrentMap<K,V>, ConcurrentNavigableMap<K,V>, LogicalMessageContext, MessageContext, NavigableMap<K,V>, SOAPMessageContext, SortedMap<K,V>, AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, Hashtable, IdentityHashMap, LinkedHashMap, PrinterStateReasons, Properties, Provider, RenderingHints, SimpleBindings, TabularDataSupport, TreeMap, UIDefaults, WeakHashMap
Map 是一种把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。 Map没有继承于Collection接口 从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。
HashMap和Hashtable的区别
HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。
HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
HashMap不能保证随着时间的推移Map中的元素次序是不变的。
注意
sychronized意味着在一次仅有一个线程能够更改Hashtable。就是说任何线程要更新Hashtable时要首先获得同步锁,其它线程要等到同步锁被释放之后才能再次获得同步锁更新Hashtable。Fail-safe和iterator迭代器相关。如果某个集合对象创建了Iterator或者ListIterator,然后其它的线程试图“结构上”更改集合对象,将会抛出ConcurrentModificationException异常。但其它线程可以通过set()方法更改集合对象是允许的,因为这并没有从“结构上”更改集合。但是假如已经从结构上进行了更改,再调用set()方法,将会抛出IllegalArgumentException异常。
结构上的更改指的是删除或者插入一个元素,这样会影响到map的结构。
HashMap可以通过下面的语句进行同步:
Map m = Collections.synchronizeMap(hashMap);
结论
Hashtable和HashMap有几个主要的不同:线程安全以及速度。仅在你需要完全的线程安全的时候使用Hashtable,而如果你使用Java 5或以上的话,请使用ConcurrentHashMap吧。- 数据结构之Map
- 数据结构总结之map
- C++存储数据结构之map
- Java 数据结构之Map总结
- 数据结构Map之TreeMap分析
- c++ 数据结构之STL之 map
- STL map, STL set之数据结构基础
- STL MAP, STL SET之数据结构基础
- STL map, STL set之数据结构基础
- C++存储数据结构之四map
- STL之map、set数据结构基础
- STL map, STL set之数据结构基础
- C++存储数据结构之四map
- C++数据结构之map----第一篇
- C++存储数据结构之四map
- STL之map、set数据结构基础
- C++之map的数据结构表示
- ECMAScript 6之Set和Map数据结构
- 打包配置内容
- 网络带宽与网络通信
- 族谱(java-ssm)
- 关于RequestDispatcher dispatcher = request.getRequestDispatcher("XXX.html");dispatcher.forward(request
- linux 中特殊符号用法详解
- 数据结构之Map
- 办公自动化学习网站
- RabbitMQ消息队列(一)
- 微信内置浏览器清除缓存
- 磁疗有用吗?磁场的镇痛镇静作用
- CSS3的过渡效果
- 【51Nod】1013 3的幂的和
- 申请百度提供的API Key,以在自己的Android应用程序中使用百度的LBS功能
- Eclipse Debug失效