java 一个对象可以有多个比较方法来根据不同的值进行排序吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4262029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can an Object have multiple Compare methods for ordering based on different values?
提问by Jason
Say I have a Song object like
假设我有一个 Song 对象,例如
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.
我当前的项目要求我们对歌曲的歌词进行搜索并返回从高到低的匹配列表。我想使用 PriorityQueue 来保存基于排名值的匹配项。
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.
通常我会简单地创建另一个对象来保存 Song 和 rank,但是这个项目不仅插入了教授提供的 GUI 界面,这要求将任何结果传递到 Song[] 数组中,而且打印出前十个值作为等级,艺术家,标题。
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.
我可以使用 toArray() 来转换队列,但是如果我使用它来存储 Song 对象以外的任何内容,它将抛出一个 ArrayStoreException。
So is this possible, or do I have to modify the existing compare method to sort by integer value?
那么这是可能的,还是我必须修改现有的比较方法以按整数值排序?
采纳答案by Michael Brewer-Davis
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:
大多数有序集合都有一个将 aComparator
作为参数的构造函数。在你的Song
类中定义一些静态比较器,然后定义如下:
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.
有一些实用程序类(例如 Guava Ordering)可以帮助您从基础构建其他比较器。
回答by Adam
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
请参阅http://download.oracle.com/javase/tutorial/collections/interfaces/order.html
回答by Reese Moore
The compareTo
method of the Comparable
interface typically offers the default comparison, if you want to provide another you should write a Comparator
object.
接口的compareTo
方法Comparable
通常提供默认的比较,如果你想提供另一个你应该写一个Comparator
对象。
回答by zockman
You could use the constructor PriorityQueue(int, Comparator<? super E>)
to use a different ordering.
您可以使用构造函数PriorityQueue(int, Comparator<? super E>)
来使用不同的顺序。
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.
PriorityQueue
除了排序之外,还有理由使用 a吗?
PriorityQueue
如果您不需要在每个新元素之后对它进行排序,不仅效率低下,而且也不能用于以不同的方式排序。PriorityQueue
每个所需的排序都需要不同的。
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>)
使用 aList
就足够了,并且可以让您随时使用不同的方式进行排序Comparator
:Collections.sort(List<T> list, Comparator<? super T>)
回答by helpermethod
Instead of implementing Comparable in Song, pass a custom Comparator to your Collection of choice.
不是在 Song 中实现 Comparable,而是将自定义 Comparator 传递给您选择的 Collection。
See Object Orderingfor further details.
有关更多详细信息,请参阅对象排序。