maven工件ComparableVersion不能很好地与java集合排序算法timsort配合使用:比较法违反了一般约定

brc7rcf0  于 2023-01-16  发布在  Java
关注(0)|答案(1)|浏览(126)

在我的项目中,maven-artifact提供的ComparableVersion被用来按版本对工件进行排序。例如,提供了这些版本(应该按//拆分)。

0.0.1576817712//0.0.3//0.0.4//0.0.4.//0.0.4.1//0.0.4.2//0.0.4.3//0.0.4.4//0.0.4.5//0.0.5//0.0.5.1//0.0.5.2//0.0.5.3//0.0.5.4//0.0.6//0.0.7//0.0.8//0.1.0//0.1.2//0.1.2.1//0.1.2.2//0.1.2.3//0.1.2.4//0.1.2.5//0.1.2.6//0.1.2.7//0.1.2.8//0.1.3//0.1.3.1//0.1.3.2//0.1.3.3//0.1.4//0.1.4.1//0.1.4.2//0.1.4.3//0.1.4.4//0.1.4.5//0.1.4.6//0.1.4.7//0.1.4.8//0.1.4.9//0.1.5//0.1.7//0.1.7.1//0.1.7.2//0.1.7.3//0.1.7.4//0.1.7.5//0.1.7.6//0.1.7.7//0.1.8//0.1.9//0.1.9.1//0.1.9.11//0.1.9.12//0.1.9.13//0.1.9.2//0.1.9.3//0.1.9.8//0.1.9.9//0.1.9.9.1//1.0.0.1//1.0.0.2//1.0.0.3//1.0.0.3.1//1.0.0.4//1.0.0.5//0.0.0.1-SNAPSHOT//0.0.11-SNAPSHOT//0.0.1576066498-SNAPSHOT//0.0.1576066912-SNAPSHOT//0.0.1576209616-SNAPSHOT//0.0.1576677646-SNAPSHOT//0.0.1576722159-SNAPSHOT//0.0.1576732580-SNAPSHOT//0.0.1576737990-SNAPSHOT//0.0.1576757185-SNAPSHOT//0.0.1576812388-SNAPSHOT//0.0.1576817712-SNAPSHOT//0.0.1576821661-SNAPSHOT//0.0.1576821977-SNAPSHOT//0.0.1576825998-SNAPSHOT//0.0.1577182101-SNAPSHOT//0.0.1577266235-SNAPSHOT//0.0.1577267400-SNAPSHOT//0.0.1577268933-SNAPSHOT//0.0.2-SNAPSHOT//0.0.3-SNAPSHOT//0.0.4-SNAPSHOT//0.0.4.1-SNAPSHOT//0.0.4.2-SNAPSHOT//0.0.4.4-SNAPSHOT//0.0.4.5-SNAPSHOT//0.0.5-SNAPSHOT//0.0.5.11151113-SNAPSHOT//0.0.5.2-SNAPSHOT//0.0.5.2.1-SNAPSHOT//0.0.5.20180829-SNAPSHOT//0.0.5.20181115-SNAPSHOT//0.0.5.4-SNAPSHOT//0.0.5.4.181113-SNAPSHOT//0.0.5.5-SNAPSHOT//0.0.6-SNAPSHOT//0.0.7-SNAPSHOT//0.0.8-SNAPSHOT//0.0.9-SNAPSHOT//0.0.91576063257-SNAPSHOT//0.0.91576066026-SNAPSHOT//0.1.0-SNAPSHOT//0.1.1-SNAPSHOT//0.1.2-SNAPSHOT//0.1.2.2-SNAPSHOT//0.1.2.3-SNAPSHOT//0.1.2.4-SNAPSHOT//0.1.2.5-SNAPSHOT//0.1.2.6-SNAPSHOT//0.1.2.7-SNAPSHOT//0.1.3-SNAPSHOT//0.1.3.1-SNAPSHOT//0.1.3.3-SNAPSHOT//0.1.3.4-SNAPSHOT//0.1.4-SNAPSHOT//0.1.4.1-SNAPSHOT//0.1.4.4-SNAPSHOT//0.1.4.5-SNAPSHOT//0.1.4.6-SNAPSHOT//0.1.4.7-SNAPSHOT//0.1.4.9-SNAPSHOT//0.1.4.l-SNAPSHOT//0.1.4.y-SNAPSHOT//0.1.4.yl-SNAPSHOT//0.1.4.yy-SNAPSHOT//0.1.5-push-SNAPSHOT//0.1.5-SNAPSHOT//0.1.5.1-SNAPSHOT//0.1.5.2-SNAPSHOT//0.1.5.3-SNAPSHOT//0.1.5.4-SNAPSHOT//0.1.5.5-SNAPSHOT//0.1.5.6-SNAPSHOT//0.1.5.l-SNAPSHOT//0.1.5.testpush-SNAPSHOT//0.1.5.y-SNAPSHOT//0.1.5.yl-SNAPSHOT//0.1.6-SNAPSHOT//0.1.7-SNAPSHOT//0.1.7.1-SNAPSHOT//0.1.7.2-SNAPSHOT//0.1.7.3-SNAPSHOT//0.1.7.4-SNAPSHOT//0.1.7.6.1-SNAPSHOT//0.1.8-SNAPSHOT//0.1.9.15-SNAPSHOT//0.1.9.16-SNAPSHOT//0.1.9.2-SNAPSHOT//0.1.9.6-SNAPSHOT//0.1.9.7-SNAPSHOT//0.1.9.9.2-SNAPSHOT//0.1.9.9.3-SNAPSHOT//0.2.0-SNAPSHOT//1.0.0.0-SNAPSHOT//1.0.0.1-SNAPSHOT//1.0.0.2-SNAPSHOT//1.0.0.3-lv-SNAPSHOT//1.0.0.3-SNAPSHOT//1.0.0.4-SNAPSHOT//1.0.0.5-SNAPSHOT//1.0.0.6-SNAPSHOT//1.0.0.7-SNAPSHOT//1.0.0.8-SNAPSHOT//1.0.0.9-SNAPSHOT//1.0.1-SNAPSHOT//1.0.1.0-SNAPSHOT//1.0.1.1-SNAPSHOT//1.0.1.2-SNAPSHOT//1.0.1.3-SNAPSHOT//

这是我的代码

String data = "...."; // the above string
String[] versions = data.split("//");
List<ComparableVersion> comparableVersions = Arrays.stream(versions).map(ComparableVersion::new).collect(Collectors.toList());
Collections.sort(comparableVersions);

并且发生了错误

java.lang.IllegalArgumentException: Comparison method violates its general contract!

    at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:866)
    at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:483)
    at java.util.ComparableTimSort.mergeForceCollapse(ComparableTimSort.java:422)
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:222)
    at java.util.Arrays.sort(Arrays.java:1312)
    at java.util.Arrays.sort(Arrays.java:1506)
    at java.util.ArrayList.sort(ArrayList.java:1464)
    at java.util.Collections.sort(Collections.java:143)

1我已经尝试过添加不同版本的maven工件依赖项,但都有相同的问题。

// version 3.8.6 3.8.7 and 3.6.3 are tried
<dependency>
   <groupId>org.apache.maven</groupId>
   <artifactId>maven-artifact</artifactId>
   <version>3.6.3</version>
</dependency>

2使用LegacyMergeSort代替timsort可以通过向jvm参数添加-Djava.util.Arrays.useLegacyMergeSort=true来解决这个问题,但是我不希望它对我项目中的所有array.sort都起作用。
那么ComparableVersion和timsort一起工作有什么问题呢?还有我该如何找到另一种方法来解决这个排序问题呢?谢谢~

g6baxovj

g6baxovj1#

请确保没有任何重复的版本号,这些版本号具有不同的字符串表示形式:

import org.apache.maven.artifact.versioning.ComparableVersion;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class Test2 {

    public static void main(String[] args) {
        String data = "0.0.1576817712//0.0.3//0.0.4//0.0.4.//0.0.4.1//0.0.4.2//0.0.4.3//0.0.4.4//0.0.4.5//0.0.5//0.0.5.1//0.0.5.2//0.0.5.3//0.0.5.4//0.0.6//0.0.7//0.0.8//0.1.0//0.1.2//0.1.2.1//0.1.2.2//0.1.2.3//0.1.2.4//0.1.2.5//0.1.2.6//0.1.2.7//0.1.2.8//0.1.3//0.1.3.1//0.1.3.2//0.1.3.3//0.1.4//0.1.4.1//0.1.4.2//0.1.4.3//0.1.4.4//0.1.4.5//0.1.4.6//0.1.4.7//0.1.4.8//0.1.4.9//0.1.5//0.1.7//0.1.7.1//0.1.7.2//0.1.7.3//0.1.7.4//0.1.7.5//0.1.7.6//0.1.7.7//0.1.8//0.1.9//0.1.9.1//0.1.9.11//0.1.9.12//0.1.9.13//0.1.9.2//0.1.9.3//0.1.9.8//0.1.9.9//0.1.9.9.1//1.0.0.1//1.0.0.2//1.0.0.3//1.0.0.3.1//1.0.0.4//1.0.0.5//0.0.0.1-SNAPSHOT//0.0.11-SNAPSHOT//0.0.1576066498-SNAPSHOT//0.0.1576066912-SNAPSHOT//0.0.1576209616-SNAPSHOT//0.0.1576677646-SNAPSHOT//0.0.1576722159-SNAPSHOT//0.0.1576732580-SNAPSHOT//0.0.1576737990-SNAPSHOT//0.0.1576757185-SNAPSHOT//0.0.1576812388-SNAPSHOT//0.0.1576817712-SNAPSHOT//0.0.1576821661-SNAPSHOT//0.0.1576821977-SNAPSHOT//0.0.1576825998-SNAPSHOT//0.0.1577182101-SNAPSHOT//0.0.1577266235-SNAPSHOT//0.0.1577267400-SNAPSHOT//0.0.1577268933-SNAPSHOT//0.0.2-SNAPSHOT//0.0.3-SNAPSHOT//0.0.4-SNAPSHOT//0.0.4.1-SNAPSHOT//0.0.4.2-SNAPSHOT//0.0.4.4-SNAPSHOT//0.0.4.5-SNAPSHOT//0.0.5-SNAPSHOT//0.0.5.11151113-SNAPSHOT//0.0.5.2-SNAPSHOT//0.0.5.2.1-SNAPSHOT//0.0.5.20180829-SNAPSHOT//0.0.5.20181115-SNAPSHOT//0.0.5.4-SNAPSHOT//0.0.5.4.181113-SNAPSHOT//0.0.5.5-SNAPSHOT//0.0.6-SNAPSHOT//0.0.7-SNAPSHOT//0.0.8-SNAPSHOT//0.0.9-SNAPSHOT//0.0.91576063257-SNAPSHOT//0.0.91576066026-SNAPSHOT//0.1.0-SNAPSHOT//0.1.1-SNAPSHOT//0.1.2-SNAPSHOT//0.1.2.2-SNAPSHOT//0.1.2.3-SNAPSHOT//0.1.2.4-SNAPSHOT//0.1.2.5-SNAPSHOT//0.1.2.6-SNAPSHOT//0.1.2.7-SNAPSHOT//0.1.3-SNAPSHOT//0.1.3.1-SNAPSHOT//0.1.3.3-SNAPSHOT//0.1.3.4-SNAPSHOT//0.1.4-SNAPSHOT//0.1.4.1-SNAPSHOT//0.1.4.4-SNAPSHOT//0.1.4.5-SNAPSHOT//0.1.4.6-SNAPSHOT//0.1.4.7-SNAPSHOT//0.1.4.9-SNAPSHOT//0.1.4.l-SNAPSHOT//0.1.4.y-SNAPSHOT//0.1.4.yl-SNAPSHOT//0.1.4.yy-SNAPSHOT//0.1.5-push-SNAPSHOT//0.1.5-SNAPSHOT//0.1.5.1-SNAPSHOT//0.1.5.2-SNAPSHOT//0.1.5.3-SNAPSHOT//0.1.5.4-SNAPSHOT//0.1.5.5-SNAPSHOT//0.1.5.6-SNAPSHOT//0.1.5.l-SNAPSHOT//0.1.5.testpush-SNAPSHOT//0.1.5.y-SNAPSHOT//0.1.5.yl-SNAPSHOT//0.1.6-SNAPSHOT//0.1.7-SNAPSHOT//0.1.7.1-SNAPSHOT//0.1.7.2-SNAPSHOT//0.1.7.3-SNAPSHOT//0.1.7.4-SNAPSHOT//0.1.7.6.1-SNAPSHOT//0.1.8-SNAPSHOT//0.1.9.15-SNAPSHOT//0.1.9.16-SNAPSHOT//0.1.9.2-SNAPSHOT//0.1.9.6-SNAPSHOT//0.1.9.7-SNAPSHOT//0.1.9.9.2-SNAPSHOT//0.1.9.9.3-SNAPSHOT//0.2.0-SNAPSHOT//1.0.0.0-SNAPSHOT//1.0.0.1-SNAPSHOT//1.0.0.2-SNAPSHOT//1.0.0.3-lv-SNAPSHOT//1.0.0.3-SNAPSHOT//1.0.0.4-SNAPSHOT//1.0.0.5-SNAPSHOT//1.0.0.6-SNAPSHOT//1.0.0.7-SNAPSHOT//1.0.0.8-SNAPSHOT//1.0.0.9-SNAPSHOT//1.0.1-SNAPSHOT//1.0.1.0-SNAPSHOT//1.0.1.1-SNAPSHOT//1.0.1.2-SNAPSHOT//1.0.1.3-SNAPSHOT"; // the above string
        String[] versions = data.split("//");
        List<ComparableVersion> comparableVersions = Arrays.stream(versions)
                .map(ComparableVersion::new)
                .distinct()
                .collect(Collectors.toList());
        Collections.sort(comparableVersions);
        System.out.println(comparableVersions);
    }
}

这里假设ComparableVersion.equals()对于任何一对你认为不相等的版本都不会返回true。
在这种情况下,0.0.40.0.4.中的后者将从流中移除。

相关问题