Can an Object have multiple Compare methods for ordering based on different values?
Say I have a Song object like
public Song(){
String artist, title;
StringBuilder lyrics;
int rank;
}
Is it possible to have multiple compare methods that, depending on the collection used, sort by a particular field? This object already has a compare method for ordering based on the artist and title values, and I would like to be able to order based on the rank.
My current project requires us to run a search on the lyrics of the Song and return a high to low match list. I want to use a PriorityQueue to hold the matches based on rank value.
Normally I would simply create another object to hold the Song and the rank, but this project not only plugs into a GUI interface provided by the professor, which requires any results be passed in an Song[] array, but prints out the first ten values as Rank, Artist, Title.
I can use toArray() to convert the queue, but if I 开发者_Go百科use it to store anything other than Song objects, it will throw an ArrayStoreException.
So is this possible, or do I have to modify the existing compare method to sort by integer value?
Use a Comparator.
Comparator<Song> rankOrder = new Comparator<Song>() {
public int compare(Song s1, Song e2) {
return s1.rank - s2.rank;
}
};
Collections.sort(songs, rankOrder);
See http://download.oracle.com/javase/tutorial/collections/interfaces/order.html
Most ordered collections have a constructor that takes a Comparator
as an argument. Define a few static comparators in your Song
class and then define things as follows:
Set<Song> allSongs = new TreeSet<Song>(Song.BY_TITLE);
PriorityQueue<Song> rankedSongs = new PriorityQueue<Song>(10, Song.BY_RANK);
There are utility classes (e.g., Guava Ordering) that can help you build up other comparators from the basics.
The compareTo
method of the Comparable
interface typically offers the default comparison, if you want to provide another you should write a Comparator
object.
You could use the constructor PriorityQueue(int, Comparator<? super E>)
to use a different ordering.
Is there a reason for using a PriorityQueue
apart from sorting?
PriorityQueue
is not only inefficient if you do not need to have it sorted after each new element but can also not be used to sort in different ways. You would need a different PriorityQueue
for each desired sorting.
Using a List
could be sufficient and would allow you to sort using a different Comparator
whenever you like: Collections.sort(List<T> list, Comparator<? super T>)
Instead of implementing Comparable in Song, pass a custom Comparator to your Collection of choice.
See Object Ordering for further details.
精彩评论