按字母顺序排序很慢

时间:2018-08-29 16:14:32

标签: java android sorting alphabetical

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

问题是,某些label包含诸如É(eE之类的字符作为第一个字符。因此,我不得不使用发现的here函数deAccent()来对它进行排序,而与重音或类似的东西无关。使用此功能,列表['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秒钟才能进行排序。

关于如何进行这种分类的任何想法?或者让它更快一点

1 个答案:

答案 0 :(得分:1)

考虑@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());

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

我在评论中建议的是隐藏deAccentedLabel,以保持Formula的公共界面尽可能整洁。因此,Formula可以提供Comparator ,而不是其他必须构建的类<​​/ strong>。 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());