package jef.common; import java.io.Serializable; import java.util.AbstractSet; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import jef.common.annotation.ObjectName; import jef.tools.ArrayUtils; import com.google.common.base.Objects; /** * 用List实现的最简单的Map,目标是占用内存最小,不考虑性能,事实上元素不多的情况下性能不是什么问题。 * * 这个类更多的时候是用来作为JAXB的通用Map序列化。在我修改了JAXB的实现之后,这一序列化将泛型的map作为一个单独的类型来使用. * * 值得注意的是,为了让JAXB序列化后不显示父类AbstractMap,这里特地进行了处理,将JDK的AbstractMap拷贝了一份出来,为了加上@XmlTransient这个标签 * 。 因此这个类没有继承JDK的AbstractMap. * * @param <K> * @param <V> */ @ObjectName("Map") @XmlAccessorType(XmlAccessType.FIELD) public class SimpleMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Serializable { private static final long serialVersionUID = -4930667933312037159L; @XmlElement(nillable = false, name = "entry") private List<jef.common.Entry<K, V>> entries; public List<jef.common.Entry<K, V>> getEntries() { return entries; } public void setEntries(List<jef.common.Entry<K, V>> entries) { this.entries = entries; } public SimpleMap(jef.common.Entry<K, V>[] entries) { this.entries = ArrayUtils.asList(entries); } public SimpleMap() { this(16); } public SimpleMap(int size) { this.entries = new ArrayList<jef.common.Entry<K, V>>(size); } @SuppressWarnings({ "rawtypes", "unchecked" }) public SimpleMap(Map<K, V> map) { if (map instanceof SimpleMap) { entries = ((SimpleMap) map).entries; } else { entries = new ArrayList<jef.common.Entry<K, V>>(map.size()); for (Entry<K, V> e : map.entrySet()) { entries.add(new jef.common.Entry<K, V>(e.getKey(), e.getValue())); } } } /** * 在Map中添加元素,不检查重复与否 * * @param key * @param value */ public void add(K key, V value) { entries.add(new jef.common.Entry<K, V>(key, value)); } /* * (non-Javadoc) * * @see jef.common.AbstractMap#put(java.lang.Object, java.lang.Object) */ @Override public V put(K key, V value) { int index = -1; for (int i = 0; i < entries.size(); i++) { if (Objects.equal(entries.get(i).getKey(), key)) { index = i; break; } } if (index > -1) { entries.set(index, new jef.common.Entry<K, V>(key, value)); } else { entries.add(new jef.common.Entry<K, V>(key, value)); } return value; } private class EntriesIterator implements Iterator<java.util.Map.Entry<K, V>> { private int n = 0; public boolean hasNext() { return n < entries.size(); } public java.util.Map.Entry<K, V> next() { java.util.Map.Entry<K, V> result = entries.get(n); n++; return result; } public void remove() { n--; entries.remove(n); } } public Set<java.util.Map.Entry<K, V>> entrySet() { return new AbstractSet<java.util.Map.Entry<K, V>>() { @Override public Iterator<java.util.Map.Entry<K, V>> iterator() { return new EntriesIterator(); } @Override public int size() { return entries.size(); } }; } @Override public int size() { return entries.size(); } @Override public void clear() { entries.clear(); } @Override public Iterator<? extends java.util.Map.Entry<K, V>> entryIterator() { return entries.iterator(); } }