软件版本比较之——Java算法实现软件版本比较

最近遇到一个开发中的小问题,软件版本比较:例如2.12.3和2.2.1这两个版本号,哪个更新。

其实,客户端版本检测更新,检测后台是否有更新版本可更新,Java中最简单的一种方法便是获取当前客户端版本号,与服务端提供的最新版本号做equals对比即可。

假设当前客户端版本号为localVersion 后台提供最新客户端版本号为onlineVersion

通过if (localVersion.equals(onlineVersion))即可判断是否有新版本。这种判断只是比较本地版本号字符串和后台版本号是否完全一致来做判断的。但这存在一个问题,假如后台版本号比当前版本号低,localVersion.equals(onlineVersion)同样为true,这样就会引起一个问题,软件会被更新为比当前版本更低的版本,显然这不是我们所期望的。

那么如何避免这个问题呢,最好做版本号大小的判断。最初想到的一个方法便是把版本号转为double型数据再进行比较 比如版本号1.2.2便通过替换掉字符串中除第一个"."之外的所有"."再通过 Double.valueOf(String)方法转换为Double类型的值进行比较。用这种方法确实可以比较版本号的大小,比如版本号1.2.2和1.2.3便是比较1.22和1.23的大小,显然比较结果版本号1.2.3大于1.2.2,结果正确。

	/**
	 * 判断是否为最新版本
	 * 
	 * @param localVersion
	 *            本地版本号
	 * @param onlineVersion
	 *            线上版本号
	 */
	public static boolean isNewVersionDouble(String localVersion, String onlineVersion)
	{
		if (localVersion == null || onlineVersion == null)
		{
			return false;
		}

		return parseStrVersionCodeToDouble(onlineVersion).compareTo(parseStrVersionCodeToDouble(localVersion)) > 0 ? true
				: false;
	}

	/**
	 * 将字符串型版本号转换为Double型版本号
	 * 
	 * @param versionCode
	 * @return
	 */
	private static Double parseStrVersionCodeToDouble(String versionCode)
	{
		if (versionCode.contains("."))
		{
			String versionStr = versionCode.substring(0, versionCode.indexOf(".") + 1)
					+ versionCode.substring(versionCode.indexOf(".") + 1).replace(".", "");
			return Double.valueOf(versionStr);
		}
		else
		{
			return Double.valueOf(versionCode);
		}
	}


后来看到网上可以直接使用String.compareTO方法比较,便尝试了,直接让onlineVersion.compareTo(localVersion) 可以达到与转换为double类型比较相同的效果。

/**
	 * String.comparTo方法
	 * 
	 * @param localVersion
	 * @param onlineVersion
	 * @return
	 */
	public static boolean isNewVersionStr(String localVersion, String onlineVersion)
	{
		if (localVersion == null || onlineVersion == null)
		{
			return false;
		}
		return onlineVersion.compareTo(localVersion) > 0 ? true : false;

	}

但上述两个方法在比较两个点之间为单位数的版本号(例如2.2.1和2.3.1)时能返回正确结果,但在比较两个点之间不都为单位数版本号(如2.2.1和2.12.1)时便返回了错误的结果,显然版本号2.12.1要大于2.2.1但返回结果却恰恰相反。为什么呢?使用转换为double 比较方法时,实际比较的是2.21和2.121这两个数值的大小,显然2.21大于2.121,这个方法返回了错误的结果不难理解。而使用String.compareTo方法时实际是依次比较字符串各个字符的Unicode value大小,显然当比到第一个小数点后的值时2>1所以便得出了版本号2.2.1大于2.12.1的错误结果。

至此,我们可以得出一个结论,直接使用String.compareTo方法可以达到转换Double再比较相同的效果,因此,第一种转换double再比较的方法就没有了存在的意义,只是更麻烦点、更低效而已。但我们比较两点之间多位版本号的目的使用String.compareTo方法并不能实现。怎么比才能在任何情况下都返回正确结果呢。我想到的一个便是通过点切分版本号为数组在依次比较数组中各个值的大小,这样就不会出现比较中认为2比12大的情况。

	/**
	 * 判断是否为最新版本方法 将版本号根据.切分为int数组 比较
	 * 
	 * @param localVersion
	 *            本地版本号
	 * @param onlineVersion
	 *            线上版本号
	 * @return
	 */
	public static boolean isAppNewVersion(String localVersion, String onlineVersion)
	{
		if (localVersion.equals(onlineVersion))
		{
			return false;
		}
		String[] localArray = localVersion.split("\\.");
		String[] onlineArray = onlineVersion.split("\\.");

		int length = localArray.length < onlineArray.length ? localArray.length : onlineArray.length;

		for (int i = 0; i < length; i++)
		{
			if (Integer.parseInt(onlineArray[i]) > Integer.parseInt(localArray[i]))
			{
				return true;
			}
			else if (Integer.parseInt(onlineArray[i]) < Integer.parseInt(localArray[i]))
			{
				return false;
			}
			// 相等 比较下一组值
		}

		return true;
	}


最后一个方法便可在比较两点之间多位的版本号时返回正确的结果。有兴趣可以复制代码运行试试。

我暂时想到的解决方法便是这个,抛砖引玉,如果有更好的、更高效、简便的比较方法,请留言赐教,谢谢!


Dijkstra算法是一种用于在加权图找到最短路径的算法,它可以处理没有负权边的图。算法的基本思想是,从源点开始,逐步增加到其他顶点的距离,直到找到最短路径为止。Dijkstra算法采用贪心策略,每次找到距离源点最近的一个未被访问的顶点,并更新其他顶点到源点的距离。 在Java实现Dijkstra算法通常需要使用优先队列来优化查找当前距离源点最近顶点的过程。以下是Dijkstra算法Java实现的一个简单例子: ```java import java.util.*; class Dijkstra { // 图的顶点数量 private static final int N = 9; // Dijkstra算法实现 public static void dijkstra(int[][] graph, int startVertex) { // 记录源点到每个顶点的最短路径 int[] dist = new int[N]; // 初始化距离数组,所有顶点距离设置为无穷大 Arrays.fill(dist, Integer.MAX_VALUE); // 用于标记顶点是否被访问过 boolean[] visited = new boolean[N]; // 起始点到自身的距离是0 dist[startVertex] = 0; // 用优先队列优化查找最小距离的顶点 PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.comparingInt(i -> dist[i])); // 将起始点加入优先队列 pq.add(startVertex); while (!pq.isEmpty()) { // 从优先队列选出距离最小的顶点 int u = pq.poll(); // 如果这个顶点已经被访问过,跳过 if (visited[u]) continue; // 标记顶点为已访问 visited[u] = true; // 遍历所有邻接的顶点 for (int v = 0; v < N; v++) { // 如果顶点u到顶点v存在边,并且顶点v未被访问 if (graph[u][v] != 0 && !visited[v]) { // 计算源点通过顶点u到顶点v的路径长度 int newDist = dist[u] + graph[u][v]; // 如果新的路径长度小于当前记录的路径长度,则更新之 if (newDist < dist[v]) { dist[v] = newDist; // 将顶点v加入优先队列 pq.add(v); } } } } // 输出从源点到每个顶点的最短路径长度 for (int i = 0; i < N; i++) { System.out.println("Distance from vertex " + startVertex + " to vertex " + i + " is " + dist[i]); } } public static void main(String[] args) { // 示例图的邻接矩阵表示 int[][] graph = { {0, 4, 0, 0, 0, 0, 0, 8, 0}, {4, 0, 8, 0, 0, 0, 0, 11, 0}, {0, 8, 0, 7, 0, 4, 0, 0, 2}, {0, 0, 7, 0, 9, 14, 0, 0, 0}, {0, 0, 0, 9, 0, 10, 0, 0, 0}, {0, 0, 4, 14, 10, 0, 2, 0, 0}, {0, 0, 0, 0, 0, 2, 0, 1, 6}, {8, 11, 0, 0, 0, 0, 1, 0, 7}, {0, 0, 2, 0, 0, 0, 6, 7, 0} }; // 从顶点0开始计算最短路径 dijkstra(graph, 0); } } ``` 在这个例子,`graph`是一个图的邻接矩阵表示,`dijkstra`方法实现了Dijkstra算法,`main`方法用于测试算法。请注意,这个例子假设图是用邻接矩阵表示的,并且顶点编号从0开始。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值