Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-对包含特殊字符的对象列表进行排序_Java_Sorting - Fatal编程技术网

Java-对包含特殊字符的对象列表进行排序

Java-对包含特殊字符的对象列表进行排序,java,sorting,Java,Sorting,基本上,我有一个对象的arraylist,如下所示: [{name: 'A'}, {name: 'B'}, {name:'?'}] 我想对这些进行排序,使问号位于上面的末尾 但是使用下面的代码 Collections.sort(myList); 这总是首先导致带有问号的对象,我认为这是由于ASCII排序?我认为正确的方法是使用一个比较器函数,但我不确定用字母和特殊字符将如何形成它 我将如何实现这一点 在Java 8中,您可以使用两层自定义比较器: // given List<YourO

基本上,我有一个对象的arraylist,如下所示:

[{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 < '?' < '!'"