diff --git a/CHANGELOG.md b/CHANGELOG.md
index b46bdb859..2cb49d66c 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
### 🐣新特性
* 【db 】 RedisDS增加user支持(issue#I8XEQ4@Gitee)
* 【core 】 MapUtil增加partition方法(pr#1170@Gitee)
+* 【core 】 增加Version类(issue#I8Z3VE@Gitee)
### 🐞Bug修复
* 【crypto】 修复BouncyCastleProvider导致graalvm应用报错UnsupportedFeatureError(pr#3464@Github)
@@ -17,6 +18,7 @@
* 【core 】 修复CollUtil.containsAll在coll2长度大于coll1时逻辑歧义问题(issue#I8Z2Q4@Gitee)
* 【poi 】 修复当sheetName 不存在时,ExcelUtil.getReader方法不会释放文件问题(issue#I8ZIQC@Gitee)
* 【crypto】 通过添加系统属性hutool.crypto.decodeHex强制关闭hex识别以解决hex和Base64歧义问题(issue#I90M9D@Gitee)
+* 【core 】 修复VersionComparator违反传递问题(issue#I8Z3VE@Gitee)
-------------------------------------------------------------------------------------------------------------
# 5.8.25(2024-01-11)
diff --git a/hutool-core/src/main/java/cn/hutool/core/comparator/VersionComparator.java b/hutool-core/src/main/java/cn/hutool/core/comparator/VersionComparator.java
index 0e12a8389..962b1b33f 100644
--- a/hutool-core/src/main/java/cn/hutool/core/comparator/VersionComparator.java
+++ b/hutool-core/src/main/java/cn/hutool/core/comparator/VersionComparator.java
@@ -1,6 +1,7 @@
package cn.hutool.core.comparator;
import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.Version;
import cn.hutool.core.util.*;
import java.io.Serializable;
@@ -13,7 +14,7 @@ import java.util.regex.Pattern;
* 比较两个版本的大小
* 排序时版本从小到大排序,即比较时小版本在前,大版本在后
* 支持如:1.3.20.8,6.82.20160101,8.5a/8.5c等版本形式
- * 参考:https://www.cnblogs.com/shihaiming/p/6286575.html
+ * 参考:java.lang.module.ModuleDescriptor.Version
*
* @author Looly
* @since 4.0.2
@@ -21,8 +22,6 @@ import java.util.regex.Pattern;
public class VersionComparator implements Comparator, Serializable {
private static final long serialVersionUID = 8083701245147495562L;
- private static final Pattern PATTERN_PRE_NUMBERS= Pattern.compile("^\\d+");
-
/** 单例 */
public static final VersionComparator INSTANCE = new VersionComparator();
@@ -64,39 +63,6 @@ public class VersionComparator implements Comparator, Serializable {
return 1;
}
- final List v1s = StrUtil.split(version1, CharUtil.DOT);
- final List v2s = StrUtil.split(version2, CharUtil.DOT);
-
- int diff = 0;
- int minLength = Math.min(v1s.size(), v2s.size());// 取最小长度值
- String v1;
- String v2;
- for (int i = 0; i < minLength; i++) {
- v1 = v1s.get(i);
- v2 = v2s.get(i);
- // 先比较长度
- diff = v1.length() - v2.length();
- if (0 == diff) {
- diff = v1.compareTo(v2);
- }else {
- // 不同长度,且含有字母
- if(!NumberUtil.isNumber(v1) || !NumberUtil.isNumber(v2)){
- //不同长度的先比较前面的数字;前面数字不相等时,按数字大小比较;数字相等的时候,继续按长度比较,类似于 103 > 102a
- final int v1Num = Convert.toInt(ReUtil.get(PATTERN_PRE_NUMBERS, v1, 0), 0);
- final int v2Num = Convert.toInt(ReUtil.get(PATTERN_PRE_NUMBERS, v2, 0), 0);
- final int diff1 = v1Num - v2Num;
- if (diff1 != 0) {
- diff = diff1;
- }
- }
- }
- if(diff != 0) {
- //已有结果,结束
- break;
- }
- }
-
- // 如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大;
- return (diff != 0) ? diff : v1s.size() - v2s.size();
+ return CompareUtil.compare(Version.of(version1), Version.of(version2));
}
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Version.java b/hutool-core/src/main/java/cn/hutool/core/lang/Version.java
new file mode 100644
index 000000000..1075bf466
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/lang/Version.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2024. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package cn.hutool.core.lang;
+
+import cn.hutool.core.comparator.CompareUtil;
+import cn.hutool.core.util.CharUtil;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 字符串版本表示,用于解析版本号的不同部分并比较大小。
+ * 来自:java.lang.module.ModuleDescriptor.Version
+ *
+ * @author Looly
+ */
+public class Version implements Comparable, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 解析版本字符串为Version对象
+ *
+ * @param v 版本字符串
+ * @return The resulting {@code Version}
+ * @throws IllegalArgumentException 如果 {@code v} 为 {@code null}或 ""或无法解析的字符串,抛出此异常
+ */
+ public static Version of(final String v) {
+ return new Version(v);
+ }
+
+ private final String version;
+
+ private final List