基本设计
- 设计思想:以空间换时间
- 实现原理:将版本号转为int数组,使用Guava Cache 对处理过的版本数据做缓存(采用lru的淘汰策略),通过int数组的比较达到比较版本的效果
依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
源码
public class CachedVersionCompareUtil {
private static Cache<String, int[]> cache = CacheBuilder.newBuilder().expireAfterWrite(1,
TimeUnit.HOURS).maximumSize(1000).build();
private static final int[] EMPTY_INT_ARRAY = new int[0];
/**
* version1 > version2 return 1
* version1 < version2 return -1
* version1 == version2 return 0
* @param version1
* @param version2
* @return
*/
public static int compare(String version1, String version2) {
int[] left = calculate(version1);
int[] right = calculate(version2);
if (left.length == 0 && right.length == 0) {
return 0;
} else if (left.length != 0 && right.length != 0) {
int index = 0;
while (index < left.length && index < right.length) {
if (left[index] == right[index]) {
index += 1;
} else {
return (left[index] < right[index]) ? -1 : 1;
}
}
if (index == left.length && index == right.length) {
return 0;
}
return index == left.length ? -1 : 1;
} else {
return left.length == 0 ? -1 : 1;
}
}
private static int[] calculate(final String version) {
if (StringUtils.isEmpty(version)) {
return EMPTY_INT_ARRAY;
}
try {
return cache.get(version, new Callable<int[]>() {
@Override
public int[] call() throws Exception {
return doCalculate(version);
}
});
} catch (Exception e) {
return doCalculate(version);
}
}
private static int[] doCalculate(String version) {
String[] array = version.split("\\.");
int[] intArray = new int[array.length];
for (int index = 0; index < array.length; index++) {
intArray[index] = NumberUtils.toInt(array[index].trim());
}
return intArray;
}
}