这几天做东西,有一个在把map类型的数据转为json数据,一直复用下边的函数,不是很懂就把源代码翻出来看了看,看完源码之后豁然开朗啊
public static final String mapJSON(Map<String,String> jsonMap){
String result = "";
if( jsonMap == null || jsonMap.size() == 0){
result += "{}";
return result;
}
result += "{root:[";
for(Map.Entry<String, String> entry:jsonMap.entrySet()){
String row = "{name:'"+entry.getKey()+"',value:'"+entry.getValue()+"'}";
result += row+",";
}
result = result.substring(0, result.length()-1);
result += "]}";
return result;
}
这个函数可以通过类名直接访问,它将传参进来的map类型的数据转为json串返回。在遍历map时用到了Map.Entry 和 Map.entrySet(),这个entry是interface Map<K,V>下的一个接口 interface Entry<K,V>,在继承map的hashmap中实现了这个entry
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry e = (Map.Entry)o;
Object k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
Object v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
public final int hashCode() {
return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
}
public final String toString() {
return getKey() + "=" + getValue();
}
/**
* This method is invoked whenever the value in an entry is
* overwritten by an invocation of put(k,v) for a key k that's already
* in the HashMap.
*/
void recordAccess(HashMap<K,V> m) {
}
/**
* This method is invoked whenever the entry is
* removed from the table.
*/
void recordRemoval(HashMap<K,V> m) {
}
}
/**
* Adds a new entry with the specified key, value and hash code to
* the specified bucket. It is the responsibility of this
* method to resize the table if appropriate.
*
* Subclass overrides this to alter the behavior of put method.
*/
void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}
entry有四个属性分别是key、value、next和hash,key和value对应的是键值对,next是hashmap中要存储的下一个值,hash代表解决冲突的hash值,这样就可以通过entry.getKey()和entry.getValue()获取相应的键值。
而map.entryset()在hashmap中的实现是
private transient Set<Map.Entry<K,V>> entrySet = null;
public Set<Map.Entry<K,V>> entrySet() {
return entrySet0();
}
private Set<Map.Entry<K,V>> entrySet0() {
Set<Map.Entry<K,V>> es = entrySet;
return es != null ? es : (entrySet = new EntrySet());
}
private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
return newEntryIterator();
}
public boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<K,V> e = (Map.Entry<K,V>) o;
Entry<K,V> candidate = getEntry(e.getKey());
return candidate != null && candidate.equals(e);
}
public boolean remove(Object o) {
return removeMapping(o) != null;
}
public int size() {
return size;
}
public void clear() {
HashMap.this.clear();
}
}
当调用entryset()方法时,返回的是Map.Entry<K,V>的集合,可以实现遍历。EntrySet 继承了 AbstractSet<Map.Entry<K,V>>,这就暗示了map的另一种遍历方式,即是通过迭代器Iterator来实现:
Iterator iterator=map.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<String, String> entry= (Entry<String, String>) iterator.next();
System.out.println("key:"+entry.getKey()+" value"+entry.getValue());
}
这种方式同样可以实现遍历。相比较来说前一种:for—each只能在java5或更高的版本中使用,如果你遍历的是一个空的map对象,for-each循环将抛出NullPointerException,因此在遍历前你总是应该检查空引用。后一种:在老版本java中这是惟一遍历map的方式。另一个好处是,你可以在遍历时调用iterator.remove()来删除entries,根据javadoc的说明,如果在for-each遍历中尝试使用此方法,结果是不可预测的。