Java 字母排序相当慢
我的问题是:我有一个自定义对象列表,其中包含一个名为label的字符串。这个列表很大,但太大了,大约有1000个对象。我想使用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
标签
进行字母排序
问题是,一些标签
包含字符,例如É
,(
,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()一样。好吧,我明白了!这是一件从未做过的事情,非常感谢!