Ai
8 Star 18 Fork 11

10km/common-java

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
FunctionCached.java 13.86 KB
一键复制 编辑 原始数据 按行查看 历史
package net.gdface.cache;
import java.lang.reflect.Modifier;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.base.Ticker;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.Weigher;
import net.gdface.guava.ObjectDeepEquals;
import static com.google.common.base.Preconditions.checkNotNull;
import static net.gdface.reflection.ConstructorUtils.invokeConstructor;
import static com.google.common.base.Preconditions.checkArgument;
/**
* 基于GUAVA {@link LoadingCache}实现类型转转换接口{@link Function},
* 当一个输入K的计算结果已经存在于缓存时,直接返回,无需再次计算,
* 避免对同一个输入数据多次重复计算。
* 适用于输入值与结果恒定对应的场景
* @author guyadong
*
* @param <K> 输入参数类型
* @param <V> 输出参数类型
*/
public class FunctionCached<K,V> implements Function<K, V> {
@SuppressWarnings("rawtypes")
private static final Function NUL_FUNCTION = Functions.constant(null);
/**
* 输入值与计算结果的映射,计算结果可能是正常计算出的V值,也可能是异常(Exception)
*/
protected final LoadingCache<K, Object> cache;
protected final Function<K, V> getterFunction;
protected final V defaultValue;
/**
* 构造方法
* @param getterFunction 原类型转换接口实现
* @param defaultValue K为{@code null}时返回的默认值
* @param cacheBuilder 外部提供的CacheBuilder实例,为{@code null}则忽略
* @since 2.7.9
*/
public FunctionCached(final Function<K, V> getterFunction,V defaultValue,CacheBuilder<Object,Object> cacheBuilder){
this.getterFunction = checkNotNull(getterFunction,"getterFunction is null");
/** 输入参数不可以是缓存实例 */
checkArgument(!(getterFunction instanceof FunctionCached),"getterFunction must not be instance of %s",getClass().getName());
this.defaultValue = defaultValue;
if(null == cacheBuilder ) {
cacheBuilder= CacheBuilder.newBuilder();
}
this.cache = cacheBuilder.build(new CacheLoader<K, Object>(){
@Override
public Object load(K key) {
try {
return asCached(getterFunction.apply(key));
} catch (Exception e) {
return e;
}
}});
}
/**
* 构造方法
* @param getterFunction 原类型转换接口实现
* @param defaultValue K为{@code null}时返回的默认值
*/
public FunctionCached(final Function<K, V> getterFunction,V defaultValue){
this(getterFunction,defaultValue,null);
}
/**
* 构造方法,
* K 为{@code null}时返回{@code null}
* @param getterFunction 原类型转换接口实现
*/
public FunctionCached(Function<K, V> getterFunction){
this(getterFunction, null);
}
/**
* 将 {@link LoadingCache}的值存储类型转为Value
* @param cached
*/
@SuppressWarnings("unchecked")
protected V asValue(Object cached ){
return (V) cached;
}
/**
* 将 value转为 {@link LoadingCache}的值存储类型
* @param value
*/
protected Object asCached(V value ){
return value;
}
/**
* 非缓存调用
* @param key
* @return {@code key}为{@code null}返回{@link #defaultValue}
*/
public V getUncached(K key){
return null == key ? defaultValue: getterFunction.apply(key);
}
/**
* 缓存调用
* @param key
* @return {@code key}为{@code null}返回{@link #defaultValue}
*/
public V get(K key){
if(null != key){
Object value = cache.getUnchecked(key);
if(value instanceof Exception) {
Throwables.throwIfUnchecked((Exception)value);
throw new RuntimeException((Exception)value);
}
return asValue(value);
}
return defaultValue;
}
/**
* 缓存调用
* @see #get(Object)
* @see com.google.common.base.Function#apply(java.lang.Object)
*/
@Override
public V apply(K input) {
return get(input);
}
/**
* 返回{@code getterFunction}的{@link FunctionCached}实例,
* 如果{@code getterFunction}为{@link FunctionCached}实例,则直接返回,否则创建新实例
* @param getterFunction
* @param defaultValue
* @param cacheBuilder 外部提供的CacheBuilder实例,为{@code null}则忽略
* @see #FunctionCached(Function, Object, CacheBuilder)
* @since 2.7.9
*/
public static <K, V> FunctionCached<K, V> of(Function<K, V> getterFunction,V defaultValue,CacheBuilder<Object,Object> cacheBuilder){
if(getterFunction instanceof FunctionCached){
return (FunctionCached<K, V>) getterFunction;
}
return builder().getterFunction(getterFunction, defaultValue).build();
}
/**
* 返回{@code getterFunction}的{@link FunctionCached}实例,
* 如果{@code getterFunction}为{@link FunctionCached}实例,则直接返回,否则创建新实例
* @param getterFunction
* @param defaultValue
* @see #of(Function, Object, CacheBuilder)
*/
public static <K, V> FunctionCached<K, V> of(Function<K, V> getterFunction,V defaultValue){
return of(getterFunction, defaultValue,null);
}
/**
* 返回{@code getterFunction}的{@link FunctionCached}实例(默认实例为{@code null})
* @param getterFunction
* @see #of(Function, Object)
*/
public static <K, V> FunctionCached<K, V> of(Function<K, V> getterFunction){
return of(getterFunction,null);
}
public static<K, V>Builder<K, V> builder(){
return new Builder<>();
}
/**
* builder for FunctionCached
* @author guyadong
*
* @param <K>
* @param <V>
* @since 2.9.6
*/
public static class Builder<K, V>{
private CacheBuilder<Object, Object> cacheBuilder;
Function<K, V> getterFunction;
private V defaultValue;
private boolean nullable;
protected Builder() {
this.cacheBuilder = CacheBuilder.newBuilder();
}
protected Builder(CacheBuilder<Object, Object> cacheBuilder, Function<K, V> getterFunction, V defaultValue,
boolean nullable) {
this.cacheBuilder = cacheBuilder;
this.getterFunction = getterFunction;
this.defaultValue = defaultValue;
this.nullable = nullable;
}
public <V1> Builder<Object[],V1> invokeFunction( MemberInvokeFunction<V1> invokeFunction){
return new Builder<Object[],V1>().keyDeepEqual().getterFunction(invokeFunction);
}
@SuppressWarnings("unchecked")
public<K1, V1> Builder<K1, V1> getterFunction( Function<K1, V1> getterFunction){
return new Builder<K1, V1>(this.cacheBuilder,checkNotNull(getterFunction,"getterFunction is null"),(V1)defaultValue,this.nullable);
}
public <K1, V1> Builder<K1, V1> getterFunction( Function<K1, V1> getterFunction,V1 defaultValue){
return new Builder<K1, V1>(this.cacheBuilder,checkNotNull(getterFunction,"getterFunction is null"),defaultValue,this.nullable);
}
/**
* 指定指{@link #getterFunction}使用恒返回{@code null}的{@code Function}实例
* @since 2.9.10
*/
@SuppressWarnings("unchecked")
public Builder<K, V> nullGetterFunction() {
this.getterFunction = (Function<K, V>)NUL_FUNCTION;
return this;
}
/**
* 指定当{@link #getterFunction}返回值为{@code null}或{@link FunctionCached#get(Object)}参数为{@code null}时返回的默认值,
* 默认为{@code null}
* @param defaultValue
*/
public Builder<K, V> defaultValue(V defaultValue) {
this.defaultValue = defaultValue;
return this;
}
/**
* 对K执行深度比较,<p>
* 对于K为数组类型时,必须指定深度比较
* @see CacheBuilder#keyEquivalence(Equivalence)
*/
public Builder<K, V> keyDeepEqual() {
ObjectDeepEquals.keyDeepEqual(cacheBuilder);
return this;
}
/**
* 允许 {@link #getterFunction}返回值为{@code null}
*/
public Builder<K, V> nullable() {
nullable = true;
return this;
}
/**
* @see CacheBuilder#initialCapacity(int)
*/
public Builder<K, V> initialCapacity(int initialCapacity) {
cacheBuilder.initialCapacity(initialCapacity);
return this;
}
/**
* @see CacheBuilder#concurrencyLevel(int)
*/
public Builder<K, V> concurrencyLevel(int concurrencyLevel) {
cacheBuilder.concurrencyLevel(concurrencyLevel);
return this;
}
/**
* @see CacheBuilder#maximumSize(long)
*/
public Builder<K, V> maximumSize(long size) {
cacheBuilder.maximumSize(size);
return this;
}
/**
* @see CacheBuilder#maximumWeight(long)
*/
public Builder<K, V> maximumWeight(long weight) {
cacheBuilder.maximumWeight(weight);
return this;
}
/**
* @see CacheBuilder#weigher(Weigher)
*/
public <K1, V1> Builder<K, V> weigher(Weigher<? super K1, ? super V1> weigher) {
cacheBuilder.weigher(weigher);
return this;
}
/**
* @see CacheBuilder#weakValues()
*/
public Builder<K, V> weakValues() {
cacheBuilder.weakValues();
return this;
}
/**
* @see CacheBuilder#softValues()
*/
public Builder<K, V> softValues() {
cacheBuilder.softValues();
return this;
}
/**
* @see CacheBuilder#expireAfterWrite(long, TimeUnit)
*/
public Builder<K, V> expireAfterWrite(long duration, TimeUnit unit) {
cacheBuilder.expireAfterWrite(duration, unit);
return this;
}
/**
* @see CacheBuilder#expireAfterAccess(long, TimeUnit)
*/
public Builder<K, V> expireAfterAccess(long duration, TimeUnit unit) {
cacheBuilder.expireAfterAccess(duration, unit);
return this;
}
/**
* @see CacheBuilder#refreshAfterWrite(long, TimeUnit)
*/
public Builder<K, V> refreshAfterWrite(long duration, TimeUnit unit) {
cacheBuilder.refreshAfterWrite(duration, unit);
return this;
}
/**
* @see CacheBuilder#ticker(Ticker)
*/
public Builder<K, V> ticker(Ticker ticker) {
cacheBuilder.ticker(ticker);
return this;
}
/**
* @see CacheBuilder#removalListener(RemovalListener)
*/
public Builder<K, V> removalListener(RemovalListener<? super K, ? super V> listener) {
cacheBuilder.removalListener(listener);
return this;
}
/**
* @see CacheBuilder#recordStats()
*/
public Builder<K, V> recordStats() {
cacheBuilder.recordStats();
return this;
}
public FunctionCached<K,V> build() {
if(nullable) {
return new FunctionCached<K,V>(getterFunction, defaultValue, cacheBuilder) {
final Optional<V> defOpt = Optional.fromNullable(defaultValue);
@SuppressWarnings("unchecked")
@Override
protected V asValue(Object cached) {
return ((Optional<V>)cached).or(defOpt).orNull();
}
@Override
protected Object asCached(V value) {
return Optional.fromNullable(value);
}
};
}
return new FunctionCached<>(getterFunction, defaultValue, cacheBuilder);
}
/**
* 将当前实例作为参数反射构建指定类型的实例<br>
* 要求目标类型构造方法第一个参数类型必须是{@link Builder}<p>
* 如果 {@code otherArgs}不为空要求构造方法第二个及以后的所有参数的类型能匹配{@code otherArgs}的类型,
* 否则抛出异常<p>
* 参见 {@link SingletonCache}
* @param <C>
* @param targetClass 目标类型
* @param otherCtorArgs 其他构造方法参数,为{@code null}或空忽略,否则要求数组元素不能为{@code null}
* @since 2.9.8
*/
public <C> C build(Class<C> targetClass,Object...otherCtorArgs) {
try {
checkArgument(targetClass != null,"targetClass is null");
if(null == otherCtorArgs || 0 == otherCtorArgs.length) {
return invokeConstructor(targetClass,this,true);
}else {
for(int i=0;i<otherCtorArgs.length;i++){
checkNotNull(otherCtorArgs[i],"otherCtorArgs[%s] is null ",i);
}
if(Modifier.isStatic(targetClass.getModifiers()) || null==targetClass.getEnclosingClass()) {
Object[] args = new Object[otherCtorArgs.length+1];
args[0] = this;
System.arraycopy(otherCtorArgs, 0, args, 1, otherCtorArgs.length);
return invokeConstructor(targetClass,args,true);
}else {
/** 非静态类 */
Object[] args = new Object[otherCtorArgs.length+1];
args[0] = otherCtorArgs[0];
args[1]=this;
System.arraycopy(otherCtorArgs, 1, args, 2, otherCtorArgs.length-1);
return invokeConstructor(targetClass,args,true);
}
}
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
}
public static abstract class MemberInvokeFunction<T> implements Function<Object[], T>{
private static String typeNameOf(Class<?> clazz) {
if (clazz.isArray()) {
try {
Class<?> cl = clazz;
int dimensions = 0;
while (cl.isArray()) {
dimensions++;
cl = cl.getComponentType();
}
StringBuilder sb = new StringBuilder();
sb.append(cl.getName());
for (int i = 0; i < dimensions; i++) {
sb.append("[]");
}
return sb.toString();
} catch (Throwable e) { /*FALLTHRU*/ }
}
return clazz.getName();
}
private static String toMemberString(String name, Class<?>[]parameterTypes) {
try {
StringBuilder sb = new StringBuilder();
if(null!=name) {
sb.append(name);
}
sb.append('(');
for (int j = 0; j < parameterTypes.length; j++) {
sb.append(typeNameOf(parameterTypes[j]));
if (j < (parameterTypes.length - 1))
sb.append(",");
}
sb.append(')');
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
}
protected static String toMemberString(String name, Object[]args) {
int arguments = args.length;
Class<?>[] parameterTypes = new Class[arguments];
for (int i = 0; i < arguments; i++) {
parameterTypes[i] = args[i].getClass();
}
return toMemberString(name,parameterTypes);
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/l0km/common-java.git
git@gitee.com:l0km/common-java.git
l0km
common-java
common-java
master

搜索帮助