CacheKey(org.apache.ibatis.cache.CacheKey),缓存键。目的是为若干个被缓存对象的组合(有顺序)生成一个key,来唯一标识这个组合。一般用作HashMap<CacheKey,Object>,作为Map对象的key存在。
CacheKey还可以在对象创建后,通过update(Object)方法或updateAll(Object[])方法,动态地向组合中追加对象(内部会通过迭代更新key值)。
CacheKey的数据结构如下:
package org.apache.ibatis.cache;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
/**
* Cache缓存对象的key
* 在HashMap中, 通过hashCode()和equals()标识key的唯一性
*
* 计算公式:hashcode=multiplier * hashcode + object.hashCode()*count
* @author Administrator
*
*/
public class CacheKey implements Cloneable, Serializable {
private static final long serialVersionUID = 1146682552656046210L;
public static final CacheKey NULL_CACHE_KEY = new NullCacheKey();
private static final int DEFAULT_MULTIPLYER = 37;
private static final int DEFAULT_HASHCODE = 17;
// 乘数,固定初始值质数37,不会变
private int multiplier;
// 当前hashCode值,初始值是质数17,
// 计算公式:hashcode=hashcode * multiplier + object.hashCode()*count
private int hashcode;
// 所有更新对象的初始hashCode的和
private long checksum;
// 更新的对象总数
private int count;
// 更新的对象集合
private List<Object> updateList;
public CacheKey() {
this.hashcode = DEFAULT_HASHCODE;
this.multiplier = DEFAULT_MULTIPLYER;
this.count = 0;
this.updateList = new ArrayList<Object>();
}
}
multiplier:乘数,是一个常数,为37(质数)
hashCode:当前CacheKey对象的hash值,通过组合中每个对象迭代计算得出。初始值为17(质数)
checksum:检验和,组合中每个对象的原始hashCode的和
count:当前组合中对象的个数
updateList:此List保存当前组合中所有的对象
CacheKey既然一般要作为HashMap的key存在,那必然要有hashCode()方法和equals(Object)方法,那么它是如何实现这两个方法的呢?
hashCode():
直接返回对象中保存的hashCode的值。hashCode的迭代公式如下:
hashCode = hashCode * multiplier + object.hashCode() * count
每次迭代一个新的对象时,count会首先+1,然后迭代hashCode值。
迭代过程的源码如下:
private void doUpdate(Object object) {
// 如果object为null则hashCode为1
// 不为null则调用hashCode()获取
int baseHashCode = object == null ? 1 : object.hashCode();
// count+1
count++;
// checksum+此对象hashCode
checksum += baseHashCode;
baseHashCode *= count;
// 重新计算hashCode
hashcode = multiplier * hashcode + baseHashCode;
// 更新列表中添加此对象
updateList.add(object);
}
2.equals(Object):
判断两个CacheKey对象相等的充分必要条件是,两个对象代表的组合序列中的每个元素必须都相等(调用equals方法返回true)。但是,为了避免每次比较都要进行一次循环(遍历组合List),CacheKey采用以下顺序进行比较:
hashCode-->checksum-->count-->updateList
比较过程中,有一个不相等,则视为两个CacheKey对象不相等。