按字母顺序排序很慢

Alphabetical sorting pretty slow

这是我的问题:我有一个自定义对象列表,其中包含一个名为标签的字符串。这个列表很大但太大了,大约有 1000 个对象。我想使用 label.

进行字母排序

问题是,一些 label 包含字符,例如 É(eE 作为第一个字符。所以我不得不使用函数 deAccent() found here 来独立于重音或其他类似的东西对它进行排序。通过使用此函数,列表 ['Gab','eaaa','Éaa'] 排序为 ['eaaa','Éaa','Gab'] 而不是 ['eaaa','Gab','Éaa']。因为当我们使用compareTo方法时,ÉG之后。这是我的资料:

private List<Formula> sortFormulaList(List<Formula> formulaList) {
    // Sort all label alphabetically
    if (formulaList.size() > 0) {
        Collections.sort(formulaList, (formula1, formula2) ->
                deAccent(formula1.getLabel()).toLowerCase().compareTo(deAccent(formula2.getLabel().toLowerCase())));
    }
    return formulaList;
}

private String deAccent(String str) {
    String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD);
    Pattern pattern = Pattern.compile("\p{InCombiningDiacriticalMarks}+");
    return pattern.matcher(nfdNormalizedString).replaceAll("");
}

如果我不使用 deAccent(),它的速度足以满足我的目的,但当我使用它时,需要 1 到 3 秒才能完成排序。

知道如何进行这样的排序吗?或者让这个更快

考虑@Henry 的出色建议,Formula 可能如下所示:

public class Formula {
    private final String label;
    private final String deAccentedLabel;

    public Formula(String label) {
        this.label = label;
        this.deAccentedLabel = deAccent(label);
    }

    public String getLabel() {
        return label;
    }

    public String getDeAccentedLabel() {
        return comparableLabel;
    }


    private String deAccent(String str) {
        String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD);
        Pattern pattern = Pattern.compile("\p{InCombiningDiacriticalMarks}+");
        return pattern.matcher(nfdNormalizedString).replaceAll("");
    }

}

那么可以这样使用:

Collections.sort(formulaList, (formula1, formula2) -> formula1.getDeAccentedLabel().toLowerCase().compareTo(formula2.getDeAccentedLabel().toLowerCase());

但是,这会通过添加 public getDeAccentedLabel() 方法公开 deAccentedLabel

我在评论中的建议是隐藏 deAccentedLabel 以保持 Formula 的 public 界面尽可能干净。因此,为了排序,Formula 提供了比较器 而不是其他 类 必须构建它 Formula 看起来像这样:

public class Formula {
    private final String label;
    private final String comparableLabel;

    public Formula(String label) {
        this.label = label;
        this.comparableLabel = deAccent(label).toLowerCase();
    }

    public String getLabel() {
        return label;
    }

    private String deAccent(String str) {
        String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD);
        Pattern pattern = Pattern.compile("\p{InCombiningDiacriticalMarks}+");
        return pattern.matcher(nfdNormalizedString).replaceAll("");
    }

    public static Comparator<Formula> getLabelComparator() {
        return (formula1, formula2) -> formula1.comparableLabel.compareTo(formula2.comparableLabel);
    }

}

并像这样使用:

Collections.sort(formulaList, Formula.getLabelComparator());