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

2023-11-13

最近遇到一个开发中的小问题,软件版本比较:例如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;
	}


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

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


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

软件版本比较之——Java算法实现软件版本比较 的相关文章

  • 如何克服原语按值传递的事实

    我有一段很长的代码来计算两个值 doubles 对我来说 我在几个地方使用了这段代码 为了坚持 DRY 原则 我应该将这段代码重构为一个很好的单元测试方法 但是我不能让它返回两个双精度数 而双精度数是原始的 因此不能按值传递和操作 我能想到
  • Hibernate注解放置问题

    我有一个我认为很简单的问题 我见过两种方式的例子 问题是 为什么我不能将注释放在字段上 让我举一个例子 Entity Table name widget public class Widget private Integer id Id G
  • Java:迭代 Collection 的最佳方法(此处为 ArrayList)

    今天 当我看到一段我已经使用了数百次的代码时 我很高兴地开始编码 迭代集合 此处为 ArrayList 出于某种原因 我实际上查看了 Eclipse 的自动完成选项 这让我想知道 在什么情况下以下循环比其他循环更好使用 经典的数组索引循环
  • 正则表达式拆分数字和字母组,不带空格

    如果我有一个像 11E12C108N 这样的字符串 它是字母组和数字组的串联 如何在中间没有分隔符空格字符的情况下分割它们 例如 我希望分割结果为 tokens 0 11 tokens 1 E tokens 2 12 tokens 3 C
  • Android在排序列表时忽略大小写

    我有一个名为路径的列表 我目前正在使用以下代码对字符串进行排序 java util Collections sort path 这工作正常 它对我的 列表进行排序 但是它以不同的方式处理第一个字母的情况 即它用大写字母对列表进行排序 然后用
  • JavaFX 中具有自定义内容的 ListView

    How i can make custom ListView with JavaFx for my app I need HBox with image and 2 Labels for each line listView 您可以通过查看
  • 按第一列排序二维数组,然后按第二列排序

    int arrs 1 100 11 22 1 11 2 12 Arrays sort arrs a b gt a 0 b 0 上面的数组已排序为 1 100 1 11 2 12 11 22 我希望它们按以下方式排序a 0 b 0 首先 如果
  • 当从服务类中调用时,Spring @Transactional 不适用于带注释的方法

    在下面的代码中 当方法内部 是从内部调用的方法外部 应该在交易范围内 但事实并非如此 但当方法内部 直接从调用我的控制器class 它受到事务的约束 有什么解释吗 这是控制器类 Controller public class MyContr
  • 在 S3 中迭代对象时出现“ConnectionPoolTimeoutException”

    我已经使用 aws java API 一段时间了 没有遇到太多问题 目前我使用的是库 1 5 2 版本 当我使用以下代码迭代文件夹内的对象时 AmazonS3 s3 new AmazonS3Client new PropertiesCred
  • 具有 java XSLT 扩展的数组

    我正在尝试使用 java 在 XSLT 扩展中使用数组 我收到以下错误 Caused by java lang ClassCastException org apache xpath objects XObject cannot be ca
  • 在游戏视图下添加 admob

    我一直试图将 admob 放在我的游戏视图下 这是我的代码 public class HoodStarGame extends AndroidApplication Override public void onCreate Bundle
  • IntelliJ - 调试模式 - 在程序内存中搜索文本

    我正在与无证的第三方库合作 我知道有一定的String存储在库深处的某个字段中的某处 我可以预测的动态值 但我想从库的 API 中获取它 有没有一种方法可以通过以下方式进行搜索 类似于全文搜索 full程序内存处于调试模式并在某个断点处停止
  • 测试弱引用

    在 Java 中测试弱引用的正确方法是什么 我最初的想法是执行以下操作 public class WeakReferenceTest public class Target private String value public Targe
  • Cucumber Java 与 Spring Boot 集成 - Spring @Autowired 抛出 NullPointer 异常

    我正在为 Spring boot 应用程序编写 cucumber java 单元测试来测试每个功能 当我与 Spring Boot 集成时 Autowired 类抛出 NullPointer 异常 Spring Boot应用程序类 Spri
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • javafx android 中的文本字段和组合框问题

    我在简单的 javafx android 应用程序中遇到问题 问题是我使用 gradle javafxmobile plugin 在 netbeans ide 中构建了非常简单的应用程序 其中包含一些文本字段和组合框 我在 android
  • 具有特定参数的 Spring AOP 切入点

    我需要创建一个我觉得很难描述的方面 所以让我指出一下想法 com x y 包 或任何子包 中的任何方法 一个方法参数是接口 javax portlet PortletRequest 的实现 该方法中可能有更多参数 它们可以是任何顺序 我需要
  • hashcode 的默认实现为以相同方式构造的对象返回不同的值

    我在这里编写一个示例代码 public class Test private int i private int j public Test TODO Auto generated constructor stub public Test
  • 如何从 Maven 存储库引用本机 DLL?

    如果 JAR 附带 Maven 存储库中的本机 DLL 我需要在 pom xml 中放入什么才能将该 DLL 放入打包中 更具体地举个例子Jacob http search maven org artifactdetails 7Cnet s
  • 在 RESTful Web 服务中实现注销

    我正在开发一个需要注销服务的移动应用程序 登录服务是通过数据库验证来完成的 现在我陷入了注销状态 退一步 您没有提供有关如何在应用程序中执行身份验证的详细信息 并且很难猜测您在做什么 但是 需要注意的是 在 REST 应用程序中 不能有会话

随机推荐

  • ASP.NET立即上手教程(2)

    什么是asp net的Web Forms Asp net Web Forms 页面框架是可升级的通用语言运行时刻 CLR 程序模型 用来在服务器端动态生成WEB页面 美国人说话就是别扭 其实Web Forms就是asp net编写的页面 作
  • 本征正交分解(POD)入门(详解)

    思来想去还是把题目从 简介 改成了 入门 详解 其实详解主要就是针对可能没接触过矩阵论的同学 我也是研一才学的 入门是指的我会解释一些名词 方便理解 另外PCA 主成分分析 本质上就是POD 只是我最近翻的热工学论文大部分都用的POD这个名
  • 楠姐技术漫话:接着唠唠社区发现

    halo 大家好很开心又和大家见面了 在第一篇 楠姐技术漫画 图计算的那些事 发布之后 楠姐收到了很多建议 鼓励和支持 非常感谢大家的喜欢 所以楠姐尽自己所能马不停蹄开始第二篇的创作 虽迟但到 本篇依然是风控算法分享 其实也依然算是图算法系
  • 从零开始搭建物联网平台(四)EMQ-X消息中间件

    物联网的消息中间件有很多 如ActiveMq RabbitMq Emq 以及自己实现的netty borker 这里为什么要选择EMQ呢 首先 在使用emqx之前我用过ActiveMq由于是国外开发的 对国内产品的支持不够好 文档和社区也远
  • c++ 使用libcurl下载网络图像

    include
  • 解决ERROR: This script does not work on Python 2.7 The minimum supported Python version is 3.7

    前言 最近因项目需要 部署区块链的网络时候 需要一个问题 运行下载的install sh脚本时候 提示出错 然后找到该脚本文件 找到对应报错的语句 发现是python的pip没有下载好的缘故 解决 问题原因知道了 然后就下载一个Pip就好
  • 家政服务小程序制作:提升生活质量、解决烦恼

    在现代快节奏的生活中 家政服务扮演着越来越重要的角色 借助家政服务小程序的制作 为用户提供便捷可靠的家务帮助已成为一种新的选择 那么家政服务小程序的制作过程是怎么样的呢 带来的好处有哪些呢 1 家政服务小程序的定义与优势 小程序是微信里面的
  • 第十八讲:神州三层交换机DHCP中继服务的配置

    当DHCP客户机和DHCP服务器不在同一个网段时 由DHCP中继传递DHCP报文 增加DHCP中继功能的好处是不必为每个网段都设置DHCP服务器 同一个DHCP服务器可以为很多个子网的客户机提供网络配置参数 即节约了成本又方便了管理 这就是
  • 流水灯实验过程

    流水灯 1 基本思路 先让P1口全为高电平 灯不亮 通过为左移 位右移动来实现依次点亮LED灯一个具有注脚的文本 1 用for循环语句嵌套 写程序 include
  • 在SpringBoot中整合其它技术

    在SpringBoot中整合其它技术 前言 一 SpringBoot整合SpringMVC 1 修改web端口 2 访问静态资源 3 添加拦截器 4 更详细的日志 二 SpringBoot整合MyBatis 1 整合连接池 2 整合myba
  • 老板说,可以在家办公,顿时办公室沸腾了……

    在美国的IT行业中 在家办公 WFH 仍然不是普遍现象 这有点匪夷所思 因为 1 员工渴望在家办公 2 有些雇主已经提供在家办公 3 反对在家办公的意见不能成立 在家办公 并不意味着 100 在家工作 从不需要去办公室 而是公司应该提供这些
  • opencv进行简单的裂缝检测

    师弟最近要使用四旋翼进行桥梁探伤 主要是用运动相机搭载在四轴上检测裂缝 就顺便搞了一下有关于裂缝检测的图像处理 算法比较简单 没有考虑太多复杂情况 在简单墙面背景下基本可以找到裂缝并框定 基本思路为 先转换彩色图为灰度图 然后进行自适应局部
  • 区块链能解决媒体行业哪些问题?

    对于最近炙手可热的区块链技术 最近流行起这样一句笑言 没有什么问题是人工智能解决不了的 如果有 那就用区块链解决 这句话虽然略显夸张 但也反映出人们对于区块链技术的高度期待 区块链有三个显著的特点 去中心化 可追溯 不可篡改 这三个特点为它
  • Linux 中不适用功能键切换TTY

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 本简要指南介绍了在类 Unix 操作系统中如何在不使用功能键的情况下切换 TTY 在进一步讨论之前 我们将了解 TTY 是什么 正如在 AskUbuntu 论坛的一个答案
  • C#中关于在一个数据库同时修改2个数据的语法使用!

    SqlCommand cmd new SqlCommand update Student set Sname updateName where Sno Sno con SqlCommand cmd2 new SqlCommand updat
  • AES对称加密工具类(GCM)

    import java io UnsupportedEncodingException import java security InvalidAlgorithmParameterException import java security
  • Java实现图片格式转换(通过ImageIO)

    文章目录 粗略介绍ImageIO 一 遍历文件夹 二 转换图片格式 视频效果演示 粗略介绍ImageIO ImageIO是javax imageio包下的一个类 用于实现Java中关于图片输入输出的一种类 这个类中所有方法均为静态方法 因此
  • 2.9 UiPath中断活动Continue的介绍和使用

    Continue的介绍 跳过当前For Each 循环内的迭代 结束本次循环 Continue控件只能用于For Each 循环中 Continue在UiPath中结合For Each循环的使用 打开设计器 在设计库中新建一个Flowcha
  • ODrive踩坑(四)AS5047P-SPI绝对值磁编码器,不需每次上电校准无刷电机,直接上电可用

    前几篇介绍了ODrive在Windows下的使用环境搭建 以及TLE5012B AS5047P的ABI配置 ODrive教程资源导航 ODrive踩坑 一 windows下使用环境的搭建 odrivetool及USB驱动的安装 ODrive
  • 软件版本比较之——Java算法实现软件版本比较

    最近遇到一个开发中的小问题 软件版本比较 例如2 12 3和2 2 1这两个版本号 哪个更新 其实 客户端版本检测更新 检测后台是否有更新版本可更新 Java中最简单的一种方法便是获取当前客户端版本号 与服务端提供的最新版本号做equals