修复VersionComparator在极端数据排序时候违反了自反性问题

This commit is contained in:
Looly 2023-09-21 11:34:05 +08:00
parent 90646bc45d
commit 6d2d57e34b
4 changed files with 52 additions and 12 deletions

View File

@ -2,12 +2,13 @@
# 🚀Changelog
-------------------------------------------------------------------------------------------------------------
# 5.8.23(2023-09-20)
# 5.8.23(2023-09-21)
### 🐣新特性
### 🐞Bug修复
* 【cron 】 修复Cron表达式range解析错误问题issue#I82CSH@Gitee
* 【core 】 修复VersionComparator在极端数据排序时候违反了自反性问题issue#I81N3H@Gitee
-------------------------------------------------------------------------------------------------------------
# 5.8.22(2023-09-13)

View File

@ -1,15 +1,12 @@
package cn.hutool.core.comparator;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.*;
import java.io.Serializable;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
/**
* 版本比较器<br>
@ -24,6 +21,8 @@ import java.util.List;
public class VersionComparator implements Comparator<String>, Serializable {
private static final long serialVersionUID = 8083701245147495562L;
private static final Pattern PATTERN_PRE_NUMBERS= Pattern.compile("^\\d+");
/** 单例 */
public static final VersionComparator INSTANCE = new VersionComparator();
@ -80,12 +79,15 @@ public class VersionComparator implements Comparator<String>, Serializable {
if (0 == diff) {
diff = v1.compareTo(v2);
}else {
//不同长度的先比较前面的数字前面数字不相等时按数字大小比较数字相等的时候继续按长度比较
int v1Num = Convert.toInt(ReUtil.get(PatternPool.NUMBERS, v1, 0), 0);
int v2Num = Convert.toInt(ReUtil.get(PatternPool.NUMBERS, v2, 0), 0);
int diff1 = v1Num - v2Num;
if (diff1 != 0) {
diff = diff1;
// 不同长度且含有字母
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) {

View File

@ -15,36 +15,59 @@ public class VersionComparatorTest {
public void versionComparatorTest1() {
int compare = VersionComparator.INSTANCE.compare("1.2.1", "1.12.1");
Assert.assertTrue(compare < 0);
// 自反测试
compare = VersionComparator.INSTANCE.compare("1.12.1", "1.2.1");
Assert.assertTrue(compare > 0);
}
@Test
public void versionComparatorTest2() {
int compare = VersionComparator.INSTANCE.compare("1.12.1", "1.12.1c");
Assert.assertTrue(compare < 0);
compare = VersionComparator.INSTANCE.compare("1.12.1c", "1.12.1");
Assert.assertTrue(compare > 0);
}
@Test
public void versionComparatorTest3() {
int compare = VersionComparator.INSTANCE.compare(null, "1.12.1c");
Assert.assertTrue(compare < 0);
// 自反测试
compare = VersionComparator.INSTANCE.compare("1.12.1c", null);
Assert.assertTrue(compare > 0);
}
@Test
public void versionComparatorTest4() {
int compare = VersionComparator.INSTANCE.compare("1.13.0", "1.12.1c");
Assert.assertTrue(compare > 0);
// 自反测试
compare = VersionComparator.INSTANCE.compare("1.12.1c", "1.13.0");
Assert.assertTrue(compare < 0);
}
@Test
public void versionComparatorTest5() {
int compare = VersionComparator.INSTANCE.compare("V1.2", "V1.1");
Assert.assertTrue(compare > 0);
// 自反测试
compare = VersionComparator.INSTANCE.compare("V1.1", "V1.2");
Assert.assertTrue(compare < 0);
}
@Test
public void versionComparatorTes6() {
int compare = VersionComparator.INSTANCE.compare("V0.0.20170102", "V0.0.20170101");
Assert.assertTrue(compare > 0);
// 自反测试
compare = VersionComparator.INSTANCE.compare("V0.0.20170101", "V0.0.20170102");
Assert.assertTrue(compare < 0);
}
@Test
@ -58,5 +81,9 @@ public class VersionComparatorTest {
public void versionComparatorTest7() {
int compare = VersionComparator.INSTANCE.compare("1.12.2", "1.12.1c");
Assert.assertTrue(compare > 0);
// 自反测试
compare = VersionComparator.INSTANCE.compare("1.12.1c", "1.12.2");
Assert.assertTrue(compare < 0);
}
}

View File

@ -0,0 +1,10 @@
package cn.hutool.http;
import org.junit.Test;
public class Issue3314Test {
@Test
public void postTest() {
String url = "https://hutool.cn/test/getList";
}
}