Может ли объект иметь несколько методов сравнения для упорядочения на основе разных значений? - PullRequest
5 голосов
/ 24 ноября 2010

Скажем, у меня есть объект Song типа

public Song(){
  String artist, title;
  StringBuilder lyrics;
  int rank;
}

Возможно ли иметь несколько методов сравнения, которые в зависимости от используемой коллекции сортируют по определенному полю? У этого объекта уже есть метод сравнения для упорядочения на основе значений художника и заголовка, и я хотел бы иметь возможность упорядочить на основе ранга.

Мой текущий проект требует, чтобы мы запустили поиск по тексту песни и вернули список совпадений от верхнего до нижнего уровня. Я хочу использовать PriorityQueue для проведения матчей на основе значения ранга.

Обычно я просто создаю другой объект для хранения Песни и звания, но этот проект не только подключается к графическому интерфейсу, предоставленному преподавателем, который требует, чтобы все результаты передавались в массив Song [], но и распечатывал первые десять значений как ранг, исполнитель, название.

Я могу использовать toArray () для преобразования очереди, но если я использую ее для хранения чего-либо, кроме объектов Song, она выдаст исключение ArrayStoreException.

Так возможно ли это, или мне нужно изменить существующий метод сравнения для сортировки по целочисленному значению?

Ответы [ 5 ]

11 голосов
/ 24 ноября 2010

Используйте Компаратор .

Comparator<Song> rankOrder =  new Comparator<Song>() {
        public int compare(Song s1, Song e2) {
            return s1.rank - s2.rank;
        }
    };
Collections.sort(songs, rankOrder);

См. http://download.oracle.com/javase/tutorial/collections/interfaces/order.html

4 голосов
/ 24 ноября 2010

Большинство упорядоченных коллекций имеют конструктор, который принимает Comparator в качестве аргумента. Определите несколько статических компараторов в вашем классе Song, а затем определите вещи следующим образом:

Set<Song> allSongs = new TreeSet<Song>(Song.BY_TITLE);
PriorityQueue<Song> rankedSongs = new PriorityQueue<Song>(10, Song.BY_RANK);

Существуют служебные классы (например, Guava Ordering ), которые могут помочь вам создать другие компараторы из основ.

4 голосов
/ 24 ноября 2010

Метод compareTo интерфейса Comparable обычно предлагает сравнение по умолчанию, если вы хотите предоставить другое, вы должны написать Comparator объект.

2 голосов
/ 24 ноября 2010

Вы можете использовать конструктор PriorityQueue(int, Comparator<? super E>), чтобы использовать другой порядок.

Есть ли причина для использования PriorityQueue помимо сортировки?PriorityQueue не только неэффективен, если вам не нужно сортировать его после каждого нового элемента, но также не может использоваться для сортировки различными способами.Для каждой желаемой сортировки вам понадобится различный PriorityQueue.

Использование List может быть достаточным и позволит вам сортировать, используя другой Comparator, когда вам нравится: Collections.sort(List<T> list, Comparator<? super T>)

1 голос
/ 24 ноября 2010

Вместо реализации Comparable в Song, передайте пользовательский Comparator в выбранную вами коллекцию.

Подробнее см. Порядок объектов .

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