- 浏览: 980221 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
package java.util; import java.util.Map.Entry; /** * This class provides a skeletal implementation of the <tt>Map</tt> * interface, to minimize the effort required to implement this interface. * AbstractMap提供了Map实现的一个基础框架,实现需要的最小功能。 * <p>To implement an unmodifiable map, the programmer needs only to extend this * class and provide an implementation for the <tt>entrySet</tt> method, which * returns a set-view of the map's mappings. Typically, the returned set * will, in turn, be implemented atop <tt>AbstractSet</tt>. This set should * not support the <tt>add</tt> or <tt>remove</tt> methods, and its iterator * should not support the <tt>remove</tt> method. * 为了提供一个unmodifiable map,编程者需要继承这个类,提供entrySet方法的实现, entrySet为提供一个Entry的视图set。set实现AbstractSet,这个不提供add和remove方法, 同时iterator不支持iterator。 * <p>To implement a modifiable map, the programmer must additionally override * this class's <tt>put</tt> method (which otherwise throws an * <tt>UnsupportedOperationException</tt>), and the iterator returned by * <tt>entrySet().iterator()</tt> must additionally implement its * <tt>remove</tt> method. * 为了提供一个可修改的Map,开发者必须重写put方法,iterator返回通过entrySet().iterator(), 同时实现iterator的remove方法, * <p>The programmer should generally provide a void (no argument) and map * constructor, as per the recommendation in the <tt>Map</tt> interface * specification. * 建议开发者必须提供一个无参的构造函数 * <p>The documentation for each non-abstract method in this class describes its * implementation in detail. Each of these methods may be overridden if the * map being implemented admits a more efficient implementation. * * <p>This class is a member of the * <a href="{@docRoot}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. * * @param <K> the type of keys maintained by this map * @param <V> the type of mapped values * * @author Josh Bloch * @author Neal Gafter * @see Map * @see Collection * @since 1.2 */ public abstract class AbstractMap<K,V> implements Map<K,V> { /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) */ protected AbstractMap() { } //待子类扩展 public V put(K key, V value) { throw new UnsupportedOperationException(); } // Views /** * Each of these fields are initialized to contain an instance of the * appropriate view the first time this view is requested. The views are * stateless, so there's no reason to create more than one of each. K,V视图集 */ transient volatile Set<K> keySet = null; transient volatile Collection<V> values = null; //待子类扩展 public abstract Set<Entry<K,V>> entrySet(); }
再来看Entry两个实现
public static class SimpleEntry<K,V> implements Entry<K,V>, java.io.Serializable { private static final long serialVersionUID = -8499721149061103585L; private final K key;//Final,不可变 private V value; /** * Creates an entry representing a mapping from the specified * key to the specified value. * * @param key the key represented by this entry * @param value the value represented by this entry */ public SimpleEntry(K key, V value) { this.key = key; this.value = value; } /** * Creates an entry representing the same mapping as the * specified entry. * * @param entry the entry to copy */ public SimpleEntry(Entry<? extends K, ? extends V> entry) { this.key = entry.getKey(); this.value = entry.getValue(); } //设置新值,返回旧值 public V setValue(V value) { V oldValue = this.value; this.value = value; return oldValue; } }
不可变的K-V对Entry
/** * An Entry maintaining an immutable key and value. This class * does not support method <tt>setValue</tt>. This class may be * convenient in methods that return thread-safe snapshots of * key-value mappings. * * @since 1.6 */ public static class SimpleImmutableEntry<K,V> implements Entry<K,V>, java.io.Serializable { private static final long serialVersionUID = 7138329143949025153L; private final K key;//final private final V value;//final /** * Creates an entry representing a mapping from the specified * key to the specified value. * * @param key the key represented by this entry * @param value the value represented by this entry */ public SimpleImmutableEntry(K key, V value) { this.key = key; this.value = value; } /** * Creates an entry representing the same mapping as the * specified entry. * * @param entry the entry to copy */ public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) { this.key = entry.getKey(); this.value = entry.getValue(); } public V setValue(V value) { throw new UnsupportedOperationException(); } }
不可变SimpleImmutableEntry,与一般的SimpleEntry的区别是Value为Final修饰,同时SetValue方法不可用。
由于put方法和k-v Entry Set的方法是待子类扩展的,我们来看看其他方法,get,remove,获取key和value的
视图集等;
//Map大小 public int size() { return entrySet().size(); } //是否为null public boolean isEmpty() { return size() == 0; } //是否包含value,遍历Entry,寻找值相等的 public boolean containsValue(Object value) { Iterator<Entry<K,V>> i = entrySet().iterator(); if (value==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getValue()==null) return true; } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (value.equals(e.getValue())) return true; } } return false; } //是否包含key,遍历Entry,寻找key相等的 public boolean containsKey(Object key) { Iterator<Map.Entry<K,V>> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) return true; } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) return true; } } return false; } //遍历Entry,寻找key对应的值 public V get(Object key) { Iterator<Entry<K,V>> i = entrySet().iterator(); if (key==null) { while (i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) return e.getValue(); } } else { while (i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) return e.getValue(); } } return null; } //遍历Entry,寻找key对应的值,移除对应的k-v,Entry,返回值value public V remove(Object key) { Iterator<Entry<K,V>> i = entrySet().iterator(); Entry<K,V> correctEntry = null; if (key==null) { while (correctEntry==null && i.hasNext()) { Entry<K,V> e = i.next(); if (e.getKey()==null) correctEntry = e; } } else { while (correctEntry==null && i.hasNext()) { Entry<K,V> e = i.next(); if (key.equals(e.getKey())) correctEntry = e; } } V oldValue = null; if (correctEntry !=null) { oldValue = correctEntry.getValue(); i.remove(); } return oldValue; } //遍历Entry,将Map的Entry,放入到当前Map中 public void putAll(Map<? extends K, ? extends V> m) { for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) put(e.getKey(), e.getValue()); } //清空Map public void clear() { entrySet().clear(); } //返回Key视图set,遍历Entry,将Map的Entry的Key放入到Set中 public Set<K> keySet() { if (keySet == null) { keySet = new AbstractSet<K>() { public Iterator<K> iterator() { return new Iterator<K>() { private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public K next() { return i.next().getKey(); } public void remove() { //与AbstractMap相关联,从Map移除Entry i.remove(); } }; } public int size() { //与AbstractMap相关联 return AbstractMap.this.size(); } public boolean isEmpty() { //与AbstractMap相关联 return AbstractMap.this.isEmpty(); } public void clear() { //与AbstractMap相关联 AbstractMap.this.clear(); } public boolean contains(Object k) { return AbstractMap.this.containsKey(k); } }; } return keySet; }
从上面可以看出Key视图set的所有操作都是与AbstractMap相关联,可以理解,
直接是AbstractMap的操作。
//获取values的视图Collection
public Collection<V> values() { if (values == null) { values = new AbstractCollection<V>() { public Iterator<V> iterator() { return new Iterator<V>() { private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public V next() { return i.next().getValue(); } public void remove() { i.remove(); } }; } public int size() { return AbstractMap.this.size(); } public boolean isEmpty() { return AbstractMap.this.isEmpty(); } public void clear() { AbstractMap.this.clear(); } public boolean contains(Object v) { return AbstractMap.this.containsValue(v); } }; } return values; }
这个与Key视图Set类似,不再讲。
//判断与Object是否相等,首先判断是否为Map,再判断Size是否相等,
再遍历Entry,对的Key是否存在,Value是否相等。
public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Map)) return false; Map<K,V> m = (Map<K,V>) o; if (m.size() != size()) return false; try { Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) { Entry<K,V> e = i.next(); K key = e.getKey(); V value = e.getValue(); if (value == null) { if (!(m.get(key)==null && m.containsKey(key))) return false; } else { if (!value.equals(m.get(key))) return false; } } } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } return true; } //所有Entry的Hash值和 public int hashCode() { int h = 0; Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) h += i.next().hashCode(); return h; } //克隆,调用的是父类的clone,克隆后key,value为null protected Object clone() throws CloneNotSupportedException { AbstractMap<K,V> result = (AbstractMap<K,V>)super.clone(); result.keySet = null; result.values = null; return result; } private static boolean eq(Object o1, Object o2) { return o1 == null ? o2 == null : o1.equals(o2); }
总结:
AbstractMap提供了一个Map的简单实现,不过没有提供put的entrySet方法,这个待子类扩展。Key视图set的所有操作都是与AbstractMap相关联,可以理解,直接是AbstractMap的操作;Value的视图Collection,同样。不可变SimpleImmutableEntry,与一般的SimpleEntry的区别是Value为Final修饰,同时SetValue方法不可用。
发表评论
-
Executors解析
2017-04-07 14:38 1244ThreadPoolExecutor解析一(核心线程池数量、线 ... -
ScheduledThreadPoolExecutor解析三(关闭线程池)
2017-04-06 20:52 4450ScheduledThreadPoolExecutor解析一( ... -
ScheduledThreadPoolExecutor解析二(任务调度)
2017-04-06 12:56 2116ScheduledThreadPoolExecutor解析一( ... -
ScheduledThreadPoolExecutor解析一(调度任务,任务队列)
2017-04-04 22:59 4986Executor接口的定义:http://donald-dra ... -
ThreadPoolExecutor解析四(线程池关闭)
2017-04-03 23:02 9096Executor接口的定义:http: ... -
ThreadPoolExecutor解析三(线程池执行提交任务)
2017-04-03 12:06 6079Executor接口的定义:http://donald-dra ... -
ThreadPoolExecutor解析二(线程工厂、工作线程,拒绝策略等)
2017-04-01 17:12 3036Executor接口的定义:http://donald-dra ... -
ThreadPoolExecutor解析一(核心线程池数量、线程池状态等)
2017-03-31 22:01 20513Executor接口的定义:http://donald-dra ... -
ScheduledExecutorService接口定义
2017-03-29 12:53 1501Executor接口的定义:http://donald-dra ... -
AbstractExecutorService解析
2017-03-29 08:27 1071Executor接口的定义:http: ... -
ExecutorCompletionService解析
2017-03-28 14:27 1586Executor接口的定义:http://donald-dra ... -
CompletionService接口定义
2017-03-28 12:39 1061Executor接口的定义:http://donald-dra ... -
FutureTask解析
2017-03-27 12:59 1324package java.util.concurrent; ... -
Future接口定义
2017-03-26 09:40 1190/* * Written by Doug Lea with ... -
ExecutorService接口定义
2017-03-25 22:14 1158Executor接口的定义:http://donald-dra ... -
Executor接口的定义
2017-03-24 23:24 1671package java.util.concurrent; ... -
简单测试线程池拒绝执行任务策略
2017-03-24 22:37 2023线程池多余任务的拒绝执行策略有四中,分别是直接丢弃任务Disc ... -
JAVA集合类简单综述
2017-03-23 22:51 920Queue接口定义:http://donald-draper. ... -
DelayQueue解析
2017-03-23 11:00 1732Queue接口定义:http://donald-draper. ... -
SynchronousQueue解析下-TransferQueue
2017-03-22 22:20 2133Queue接口定义:http://donald-draper. ...
相关推荐
AbstractMap抽象类是Java集合框架中的一个重要组件,为Map接口提供了一个骨架实现。它提供了一些简单且通用的方法,但其中有两个方法非常值得关注,即keySet和values方法。这些方法的源码实现可以说是教科书式的典范...
- **AbstractMap**: `Map`的抽象基类。 #### 4. 实现类举例 - **ArrayList**: 基于数组的`List`实现。 - **LinkedList**: 基于链表的`List`实现。 - **HashSet**: 基于哈希表的`Set`实现。 - **TreeSet**: 基于红黑...
4. 抽象实现:如AbstractList、AbstractSet和AbstractMap,提供部分实现,帮助开发者快速构建自己的集合实现。 总的来说,Java集合框架是Java开发中不可或缺的一部分,它为开发者提供了强大而灵活的数据管理工具,...
- 抽象类如`AbstractCollection`、`AbstractList`和`AbstractMap`为自定义集合类提供了一些默认实现,降低了开发者的实现难度。 - 实现类如`ArrayList`、`LinkedList`、`HashMap`等提供了具体的存储和操作机制。 ...
`HashMap`、`Hashtable`和`HashSet`都是基于`Map`或`Set`接口实现的不同数据结构,它们在功能、线程安全性和性能等方面有显著差异。 首先,`HashMap`和`Hashtable`都实现了`Map`接口,这意味着它们都可以存储键值对...
- **AbstractMap**:实现了Map接口的一部分。 3. **实现类**: - **LinkedList**:实现了List接口,使用链表结构存储元素,支持快速的插入和删除操作。 - **ArrayList**:实现了List接口,基于动态数组,适合...
AbstractCollection、AbstractList、AbstractSet和AbstractMap等抽象类提供了接口的一些默认实现,方便开发者创建自定义集合类。还有一些实现类,如ArrayList、LinkedList、HashSet、HashMap等,它们提供了常用的...
- **定义**:这两个类分别提供了可变和不可变的Map.Entry实现。 - **特点**: - `SimpleEntry` 支持键值对的动态修改。 - `SimpleImmutableEntry` 则不允许修改键值对,确保了数据的一致性。 #### 3. 存在类的...
在Java编程语言中,HashMap是一种常用的集合类,它实现了Map接口,用于存储键值对(key-value pairs)。HashMap的工作基于哈希表数据结构,提供快速的插入、删除和查找操作。下面我们将深入探讨HashMap的实现原理,...
- `HashMap`继承自`AbstractMap`,实现了`Map`, `Cloneable`, `Serializable`接口。 - `HashTable`继承自`Dictionary`,同样实现了`Map`, `Cloneable`, `Serializable`接口。 #### 2. 线程安全性 - `HashTable`是...
虽然在实际的地图类`Map`中,这些方法不需要实现,但为了组合模式的统一性,它们依然存在。 接着,我们创建了两个具体的类:`Map`和`MapBag`。`Map`类代表单个地图,不包含子对象,因此其`getChildren`、`addChild`...
若需线程安全版本,可通过`Collections.synchronizedMap(new HashMap())`实现。 - **ConcurrentHashMap**: 线程安全,通过内部使用锁分段机制来提高并发性能。 ##### 3. Key/Value是否允许为空 - **Hashtable**: ...
- `Hashtable`继承自`Dictionary`类,`HashMap`继承自`AbstractMap`,两者都实现了`Map`接口。 - 线程安全:`Hashtable`的方法是同步的,适合多线程环境,而`HashMap`在默认情况下是非同步的,适合单线程环境。 -...
Note that AbstractMap fields are used * for keySet() and values(). */ transient Set<Map.Entry,V>> entrySet; /** * The number of key-value mappings contained in this map. */ transient int size; 和...
- `HashMap`继承自`AbstractMap`,实现了`Map`接口,并且还实现了`Cloneable`和`Serializable`接口。 - `Hashtable`继承自`Dictionary`,同样实现了`Map`接口,并且同样实现了`Cloneable`和`Serializable`接口。 ...
- `Hashtable` 直接继承自 `Dictionary` 类,而 `HashMap` 继承自 `AbstractMap`,并实现了 `Map` 接口。这使得 `HashMap` 更加符合面向对象的设计原则,且可以利用抽象类的一些特性,如 `AbstractMap` 提供了部分...
- **接口与抽象类**:对比List、Set和Map接口与AbstractList、AbstractSet和AbstractMap抽象类的区别。 - **泛型**:使用泛型提高代码安全性,理解类型擦除。 3. **字符串操作**: - **String对象不可变性**:...