Сортировка JList с использованием метода сортировки коллекций

Я хотел бы отсортировать свой список пользователей в списке каналов IRC, который хранится как JList, используя метод сортировки коллекций. Код ниже выполняет это в некоторой степени:

users — это JList, содержащий пользователей.

userList — это промежуточная структура данных (LinkedList), которая используется для сортировки списка с коллекциями.

// Iterate through the JList and add the users to a LinkedList of strings.
for(Object userName : users.toArray())
    userList.add(userName.toString());

// Sort
Collections.sort(userList);              

// Clear the user list (removes all users).
users.clear();                            

// Put the sorted userList in users again.
while(iterator.hasNext() && i < userList.size()) 
     users.addElement(userList(get(i++));

Проблема в том, что в списке каналов IRC есть три группы пользователей: операторы-операторы, озвученные пользователи и обычные пользователи, и они должны быть организованы в иерархию. Конечно, метод сортировки этого не учитывает. Кроме того, метод сортировки различает строчные и заглавные буквы, а это нежелательно.

Обобщенные вопросы:

Как обрабатывать сортировку различных групп пользователей; могу ли я каким-то образом указать его с помощью метода сортировки коллекций, чтобы он соответствовал иерархии?

Как запретить методу сортировки различать строчные и заглавные буквы?

Мои предлагаемые решения:

  • (Неэффективно!) Создайте три списка и добавьте в них соответствующие группы пользователей, отсортируйте, а затем добавьте их в список в удобном порядке.
  • преобразовать имена пользователей в нижний регистр (к сожалению).

Какие-либо предложения? Спасибо.


person dueland    schedule 22.11.2011    source источник


Ответы (1)


  • реализовать компаратор, который может обрабатывать иерархическую сортировку
  • используйте Collator.getInstance для сортировки строк с учетом локали

Вот фрагмент кода для пользовательского компаратора

public static class UserComparator implements Comparator<User> {

    private Collator collator = Collator.getInstance(); 

    @Override
    public int compare(User o1, User o2) {
        int compare = compareString(o1.getGroup(), o2.getGroup());
        if (compare == 0) {
            return compareString(o1.getName(), o2.getName());
        }
        return compare;
    }

    private int compareString(String o1, String o2) {
        return collator.compare(o1, o2);
    }

}

Collator использует сортировку с учетом регистра в соответствии с данной/текущей локалью, которая может (например, в Германии) или не может игнорировать (например, в США, если я правильно помню) регистр. Если вы хотите всегда игнорировать, просто измените compareString, чтобы использовать o1.compareToIgnoreCase (o2)

К вашему сведению, JXList проекта SwingX поддерживает сортировку по умолчанию (тот же механизм, что и JTable), никаких акробатических трюков не требуется, просто предоставьте компаратор для использования

 JXList list = new JXList(userListModel);
 list.setComparator(new UserComparator());
 list.setAutoCreateRowSorter(true);
 list.setSortOrder(SortOrder.ASCENDING); 
person kleopatra    schedule 22.11.2011
comment
@ user1059582, Спасибо, мам* - person mre; 22.11.2011
comment
kleopatra, решение работает, но некоторые символы идут впереди @, например [ и _. Есть ли у вас какие-либо решения, чтобы исправить это? Я пробовал и пытался с переменным успехом, и я думаю, что моя неудача связана с неполным пониманием того, как работает компаратор. - person dueland; 24.11.2011