按字母顺序排序很慢
Alphabetical sorting pretty slow
这是我的问题:我有一个自定义对象列表,其中包含一个名为标签的字符串。这个列表很大但太大了,大约有 1000 个对象。我想使用 label
.
进行字母排序
问题是,一些 label
包含字符,例如 É
、(
、e
或 E
作为第一个字符。所以我不得不使用函数 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());
这是我的问题:我有一个自定义对象列表,其中包含一个名为标签的字符串。这个列表很大但太大了,大约有 1000 个对象。我想使用 label
.
问题是,一些 label
包含字符,例如 É
、(
、e
或 E
作为第一个字符。所以我不得不使用函数 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());