Java - сортировка списка объектов, включающего специальный символ - PullRequest
2 голосов
/ 03 апреля 2020

По существу, у меня есть массив объектов, таких как:

[{name: 'A'}, {name: 'B'}, {name:'?'}]

Я хочу отсортировать их так, чтобы знак вопроса был в конце, как указано выше.

Но используя приведенный ниже код.

Collections.sort(myList);

Это всегда приводит к тому, что сначала объект с вопросительным знаком, я думаю, это связано с упорядочением ASCII? Я думаю, что правильный путь вперед - это использовать функцию сравнения, но я не уверен, как это будет складываться с буквами и специальными символами?

Как бы это реализовать?

Ответы [ 3 ]

2 голосов
/ 03 апреля 2020

Альтернативный подход - тот, который сортирует любую пунктуацию до конца - может быть достигнут с использованием основанного на правилах коллатератора .

Пример:

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 + " ");
});

Это выводит:

cat dog pig rat 123 456 !rat ?cat ?dog 

Примечания:

1) Этот конкретный c пример ограничен в Engli sh сопоставление.

2) Общая техника работает, потому что все не упомянутые символы сортируются до конца. Таким образом, не только символы пунктуации сортируются после английских sh букв и цифр, но и любой другой символ / символ (например, символы, используемые в других скриптах).

3) Если вы хотите упорядочить не в Юникоде символов пунктуации, они должны быть заключены в одинарные кавычки в строке правила:

"... < 0,1,2,3,4,5,6,7,8,9 < '?' < '!'"
1 голос
/ 03 апреля 2020

Вы можете использовать некоторые полезные методы из java.util.Comparator, чтобы сделать вашу жизнь проще и ваш код менее подвержен ошибкам, чем думать о if-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: '?'}]
    }
}
1 голос
/ 03 апреля 2020

В Java 8 вы можете использовать двухуровневый пользовательский компаратор:

// given
List<YourObject> list;
list.sort((o1, o2) -> "?".equals(o1.getName()) ? 1 :
    ("?".equals(o2.getName()) ? -1 : o1.getName().compareTo(o2.getName())));

Логика сортировки c здесь такова, что если одно или другое имя будет ?, то мы всегда сортируйте, что ? последний. Если оба имени будут ?, или если ни одно из них не будет ?, то мы сортируем, используя лексикографическую сортировку строк по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...