package com.dianping.pigeon.util;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
/**
* @author qi.yin
* 2016/11/08 下午7:36.
*/
public class MapUtils {
public static <K, V> V getOrCreate(Map<K, V> map, K key, ObjectFactory<? extends V> objectFactory) {
V ret = map.get(key);
if (ret != null) {
return ret;
}
synchronized (map) {
ret = (V) map.get(key);
if (ret == null) {
try {
ret = objectFactory.createObject();
} catch (Exception e) {
throw new IllegalStateException("error create object from factory:" + objectFactory, e);
}
map.put(key, ret);
}
}
return ret;
}
public static <K, V, T extends V> V getOrCreate(Map<K, V> map, K key, Class<T> clazz) {
return getOrCreate(map, key, new ReflectObjectFactory<T>(clazz));
}
public static <K, V> V getOrCreate(ConcurrentMap<K, V> map, K key, ObjectFactory<? extends V> objectFactory) {
V ret = map.get(key);
if (ret != null) {
return ret;
} else {
ret = objectFactory.createObject();
V last = map.putIfAbsent(key, ret);
if (last == null) {
return ret;
} else {
return last;
}
}
}
public static <K, V, T extends V> V getOrCreate(ConcurrentMap<K, V> map, K key, Class<T> clazz) {
return getOrCreate(map, key, new ReflectObjectFactory<T>(clazz));
}
public static class ReflectObjectFactory<T> implements ObjectFactory<T> {
private Class<T> clazz;
public ReflectObjectFactory(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public T createObject() {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new IllegalStateException("error create object for " + clazz, e);
}
}
@Override
public Class<T> getObjectClass() {
return clazz;
}
@Override
public String toString() {
return "object class:" + clazz;
}
}
}