【问题标题】:Java version number sortJava版本号排序
【发布时间】:2013-12-04 12:13:00
【问题描述】:
String[] k1 = {"0.10", "0.2", "0.1", "0", "1.10", "1.2", "1.1", "1", "2.10", "2", "2.2", "2.1"};
double[] k2 = {0.10, 0.2, 0.1, 0, 1.10, 1.2, 1.1, 1, 2.10, 2, 2.2, 2.1};
Arrays.sort(k1);
Arrays.sort(k2);
System.out.println(Arrays.toString(k1));
System.out.println(Arrays.toString(k2));

输出:

[0,   0.1, 0.10, 0.2,  1,   1.1, 1.10, 1.2,  2,   2.1, 2.10, 2.2]
[0.0, 0.1, 0.1,  0.2,  1.0, 1.1, 1.1,  1.2,  2.0, 2.1, 2.1,  2.2]

我想要什么,

[0, 0.1, 0.2, 0.10, 1, 1.1, 1.2, 1.10, 2, 2.1, 2.2, 2.10]

小数之前和之后的第一个排序。如 1、1.1、1.2、1.10、2、2.1 等。

如何为此编写比较器?

【问题讨论】:

  • 不是很清楚:你的双数组似乎可以解决问题。是否要删除重复值?
  • 先向我们展示您尝试过的内容。为什么不使用 TreeSet?
  • @user2378231 在双 1.1 和 1.10 中将被视为 1.1,但我想要 1.1、1.10
  • 但是为什么要 1.10 大于 1.2??
  • 基本上这些是地图的关键。我检索密钥集并希望它对其进行排序,因为我的操作取决于顺序。我无法控制地图。

标签: java sorting comparator


【解决方案1】:
2.1, 2.2, 2.10]

由于 2.10 按此顺序大于 2.2,因此看起来像是版本号排序:

import java.util.Arrays;
import java.util.Comparator;

public class VersionNumberComparator implements Comparator<String> {
  @Override
  public int compare(String version1, String version2) {
    String[] v1 = version1.split("\\.");
    String[] v2 = version2.split("\\.");
    int major1 = major(v1);
    int major2 = major(v2);
    if (major1 == major2) {
      return minor(v1).compareTo(minor(v2));
    }
    return major1 > major2 ? 1 : -1;
  }

  private int major(String[] version) {
    return Integer.parseInt(version[0]);
  }

  private Integer minor(String[] version) {
    return version.length > 1 ? Integer.parseInt(version[1]) : 0;
  }

  public static void main(String[] args) {
    String[] k1 = { "0.10", "0.2", "0.1", "0", "1.10", "1.2", "1.1", "1",
        "2.10", "2", "2.2", "2.1" };
    Arrays.sort(k1, new VersionNumberComparator());
    System.out.println(Arrays.asList(k1));
  }
}

【讨论】:

  • 我正在使用术语“标题级别排序”进行搜索,但找不到任何结果。谢谢你。
  • 比较方法的最后一行不应该是1 : -1而不是1 : 0吗?
【解决方案2】:
package com.poc.sort;

/**
 * @author voyger_india
 *
 */
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections4.CollectionUtils;

public class TestChapterSort {

    public static void main(String[] args) {
        List<String> chapters = new ArrayList<String>();

        chapters.add("1.1");
        chapters.add("1.2");
        chapters.add("1");
        chapters.add("1.3");
        chapters.add("1.1.1");
        chapters.add("5.6");
        chapters.add("1.1.10");
        chapters.add("4");
        chapters.add("1.1.9");
        chapters.add("1.2.1.10");
        chapters.add("2.1.1.4.5");
        chapters.add("1.2.1.9");
        chapters.add("1.2.1");
        chapters.add("2.2.2");
        chapters.add("1.2.1.11");

        TestChapterSort wer = new TestChapterSort();
        System.out.println(wer.sortChapters(chapters));
    }

    private List<String> sortChapters(List<String> chapters) {
        List<String> sortedChapters = new ArrayList<String>(0);

        int index;
        for (String currChapter : chapters) {
            if (!sortedChapters.contains(currChapter)) {
                index = getInsertIndex(sortedChapters, currChapter);
                sortedChapters.add(index, currChapter);
                System.out.println(sortedChapters);
            }
        }

        return sortedChapters;
    }

    private int getInsertIndex(List<String> sortChapters, String currChapter) {
        int insertIndex = 0;
        if (!CollectionUtils.isEmpty(sortChapters)) {
            int compChapterSub;
            int currChapterSub;
            String[] currChapterAr = currChapter.split("\\.");
            for (String compChapter : sortChapters) {
                String[] compChapterAr = compChapter.split("\\.");
                for (int subLvl = 0; subLvl < 5; subLvl++) {
                    compChapterSub = parseToInt(compChapterAr, subLvl);
                    currChapterSub = parseToInt(currChapterAr, subLvl);
                    if (compChapterSub == currChapterSub) {
                        continue;
                    } else if (compChapterSub == 0 && currChapterSub == 0) {
                        break;
                    } else if (compChapterSub > currChapterSub) {
                        if (checkIfProper(subLvl, compChapterAr, currChapterAr)) {
                            return insertIndex;
                        }
                    }
                }
                insertIndex++;
            }
        } else {
            return 0;
        }
        return insertIndex;
    }

    private int parseToInt(String[] subChapter, int subLvl) {
        try {
            return Integer.parseInt(subChapter[subLvl]);
        } catch (ArrayIndexOutOfBoundsException ae) {
            return 0;
        }
    }

    private boolean checkIfProper(int subLvl, String[] compChapterAr, String[] currChapterAr) {
        int subLvlCk = subLvl - 1;
        int compChapterSub;
        int currChapterSub;
        while (subLvlCk > -1) {
            compChapterSub = parseToInt(compChapterAr, subLvlCk);
            currChapterSub = parseToInt(currChapterAr, subLvlCk);
            if (compChapterSub < currChapterSub) {
                return false;
            }
            subLvlCk--;
        }
        return true;
    }

}

【讨论】:

  • 完美运行。不知道能不能把它打包成Comparator?
【解决方案3】:

我认为你想要的是不可能实现的。考虑这个简单的例子:

public static void main(String[] args) {
    double d = 0.1;
    System.out.println(d);
    d = 0.10;
    System.out.println(d);
    d = 0.100;
    System.out.println(d);
}

打印:

0.1
0.1
0.1

对于 java 0.1 double 与 0.10 和 0.100 相同。 没有双 0.1、0.10、0.100 等,只有 0.1

【讨论】:

    【解决方案4】:

    您可以编写一个 Comperator,首先将值转换为 double 并比较它们,如果它们相等,例如“0.10”和“0.1”,您应该按长度比较它们。

    【讨论】:

      猜你喜欢
      • 2011-11-22
      • 2011-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多