Java-对包含特殊字符的对象列表进行排序
基本上,我有一个对象的arraylist,如下所示:Java-对包含特殊字符的对象列表进行排序,java,sorting,Java,Sorting,基本上,我有一个对象的arraylist,如下所示: [{name: 'A'}, {name: 'B'}, {name:'?'}] 我想对这些进行排序,使问号位于上面的末尾 但是使用下面的代码 Collections.sort(myList); 这总是首先导致带有问号的对象,我认为这是由于ASCII排序?我认为正确的方法是使用一个比较器函数,但我不确定用字母和特殊字符将如何形成它 我将如何实现这一点 在Java 8中,您可以使用两层自定义比较器: // given List<YourO
[{name: 'A'}, {name: 'B'}, {name:'?'}]
我想对这些进行排序,使问号位于上面的末尾
但是使用下面的代码
Collections.sort(myList);
这总是首先导致带有问号的对象,我认为这是由于ASCII排序?我认为正确的方法是使用一个比较器函数,但我不确定用字母和特殊字符将如何形成它
我将如何实现这一点 在Java 8中,您可以使用两层自定义比较器:
// given
List<YourObject> list;
list.sort((o1, o2) -> "?".equals(o1.getName()) ? 1 :
("?".equals(o2.getName()) ? -1 : o1.getName().compareTo(o2.getName())));
这里的排序逻辑是,如果一个或其他名称是?,那么我们总是对其排序?最后的如果两个名称都是?,或者两者都不是?,那么我们将使用默认的字典式字符串排序。您可以使用java.util.Comparator中的一些有用方法,使您的生活更轻松,代码更不容易出错,而不必考虑else或三元运算符:
class MyObj {
private String name;
MyObj(String name) {
this.name = name;
}
String getName() {
return name;
}
@Override
public String toString() {
return "{name: '" + name + "'}";
}
}
public class Demo {
public static void main(String[] args) {
List<MyObj> lst = Arrays.asList(new MyObj("B"), new MyObj("?"), new MyObj("A"));
Comparator<String> questionMarksLast = Comparator
.<String, Boolean>comparing("?"::equals)
.thenComparing(Comparator.naturalOrder());
lst.sort(Comparator.comparing(MyObj::getName, questionMarksLast));
System.out.println(lst); // prints [{name: 'A'}, {name: 'B'}, {name: '?'}]
}
}
另一种方法——将任何标点符号排序到末尾——可以使用 例如:
List<String> words = Arrays.asList(
"?dog", "rat", "456", "123", "dog", "pig", "?cat", "!rat", "cat"
);
String englishRules = ("< a,A < b,B < c,C < d,D < e,E < f,F "
+ "< g,G < h,H < i,I < j,J < k,K < l,L "
+ "< m,M < n,N < o,O < p,P < q,Q < r,R "
+ "< s,S < t,T < u,U < v,V < w,W < x,X "
+ "< y,Y < z,Z < 0,1,2,3,4,5,6,7,8,9");
RuleBasedCollator rbc = new RuleBasedCollator(englishRules);
rbc.setStrength(Collator.PRIMARY);
Collections.sort(words, rbc);
words.forEach((word) -> {
out.print(word + " ");
});
注意事项:
1此特定示例仅限于英文排序规则
2由于所有未提及的字符都被排序到末尾,所以一般技术是有效的。因此,不仅标点符号按英文字母和数字排序,其他字符/符号(如其他脚本使用的字符/符号)也按英文字母和数字排序
3如果需要标点符号的非Unicode排序,则需要在规则字符串中用单引号括起来:
"... < 0,1,2,3,4,5,6,7,8,9 < '?' < '!'"
您需要重新考虑这一点:如果两个参数都为?,则比较器应返回0,但您的版本不返回0?。相等于1°?。equalso2?0:1:?。相等2-1:o1.compareToo2-虽然我可能不会在这里使用三元。@Dirk我修正了它。在黑暗的房间里用手机打电话,对不起。我只是想去掉三元:int diff=o1.compareToo2;如果diff==0,则返回diff;if?.equalso1返回1;如果?.equals2返回-1;返回差;你能解释一下你是如何在上一次编辑中修复这两个名字的吗??我认为使用Comparator.comparing和thenComparing可以使代码不那么容易出错,请参见我的答案,以获取示例。
"... < 0,1,2,3,4,5,6,7,8,9 < '?' < '!'"