开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜