Java 字母排序相当慢

Java 字母排序相当慢,java,android,sorting,alphabetical,Java,Android,Sorting,Alphabetical,我的问题是:我有一个自定义对象列表,其中包含一个名为label的字符串。这个列表很大,但太大了,大约有1000个对象。我想使用标签进行字母排序 问题是,一些标签包含字符,例如É,(,e或e作为第一个字符。因此,我不得不使用deAccent()函数对其进行排序,而与重音或其他类似的东西无关。使用此函数,列表['Gab'、'eaaa'、'eaaa']的排序方式是['eaaa'、'eaa'、'Gab']而不是['eaaa'、'Gab'、'eaa']。因为当我们使用比较方法时,在G之后。以下是我的: p

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

问题是,一些
标签
包含字符,例如
É
e
e
作为第一个字符。因此,我不得不使用
deAccent()
函数对其进行排序,而与重音或其他类似的东西无关。使用此函数,列表
['Gab'、'eaaa'、'eaaa']
的排序方式是
['eaaa'、'eaa'、'Gab']
而不是
['eaaa'、'Gab'、'eaa']
。因为当我们使用
比较方法时,
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("");
}
私有列表排序公式列表(列表公式列表){
//按字母顺序排列所有标签
如果(formulaList.size()>0){
集合.排序(公式列表,(公式1,公式2)->
deAccent(formula1.getLabel()).toLowerCase().compareTo(deAccent(formula2.getLabel().toLowerCase());
}
返回公式列表;
}
私有字符串终止(字符串str){
字符串nfdNormalizedString=Normalizer.normalize(str,Normalizer.Form.NFD);
Pattern Pattern=Pattern.compile(\\p{InCombiningDiacriticalMarks}+);
返回pattern.matcher(nfdNormalizedString.replaceAll(“”);
}
如果我不使用
deAccent()
它对我来说足够快,但是当我使用它时,排序需要1到3秒


你知道我该如何做这样的分类吗?或者让这个分类更快一些

考虑一下@Henry的优秀建议,
公式可能是这样的:

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 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());
然后可以这样使用:

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 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());
但是,这会通过添加
public getdeAccendLabel()
方法公开
deAccendLabel

我在评论中建议的是隐藏
deAccectedLabel
,以保持
Formula
的公共界面尽可能干净。因此,为了排序,
Formula
提供了比较器,而不是其他必须构建它的类
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 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());

您试图在deAccent方法中执行什么操作。也许可以对其进行优化。例如,您可以预编译模式,而不是每次调用都编译模式。@Venkatanarayamalireddy我编辑了我的帖子,以使其更清晰。比较器将被称为O(n log n)平均次数。因此,如果您预处理数据,使每个对象只调用一次deAccent,您将获得很好的加速。感谢@Glains,通过对模式进行预编译,它会更快,几乎就像没有deAccent()一样。好吧,我明白了!这是一件从未做过的事情,非常感谢!