Can an object have several comparison methods for ordering based on different values?

Say I have a Song object, for example

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

Is it possible to have several comparison methods that, depending on the collection used, are sorted by a specific field? This object already has a comparison method for ordering based on the values โ€‹โ€‹of the artist and name, and I would like to be able to order on the basis of rank.

In my current project, we need to start a search for a Song song and return a high to low list. I want to use PriorityQueue to store matches based on rank value.

Usually I would simply create another object to store the song and rank, but this project not only connects to the GUI interface provided by the professor, which requires that any results be transferred in the Song [] array, but print the first ten values โ€‹โ€‹as Rank, Artist, Title.

I can use toArray () to convert the queue, but if I use it to store anything other than Song objects, it will throw an ArrayStoreException.

So, is this possible, or do I need to modify an existing comparison method to sort by integer value?

+4
source share
5 answers

Most ordered collections have a constructor that takes a Comparator as an argument. Define some static comparators in your Song class, and then define the following things:

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

Utility classes exist (e.g. Guava Ordering ) that can help you build other comparators from the basics.

+4
source

Use 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

+9
source

The compareTo method of the Comparable interface usually offers a default comparison, if you want to provide another, you must write Comparator .

+4
source

You can use the PriorityQueue(int, Comparator<? super E>) constructor PriorityQueue(int, Comparator<? super E>) to use a different order.

Is there any reason to use PriorityQueue other than sorting? PriorityQueue not only inefficient if you do not need to sort it after each new element, but also cannot be used for sorting in different ways. For each sort you want, you need a different PriorityQueue .

Using List can be sufficient and allow you to sort using another Comparator whenever you want: Collections.sort(List<T> list, Comparator<? super T>)

+2
source

Instead of implementing Comparable in Song, pass the custom Comparator to your collection.

For more details, see Ordering an object .

+1
source

All Articles