[英]Java sort a list with revelance comparator
I'm trying to sort a list of music by revelance corresponding to a list of criteria. 我正在尝试根据与条件列表相对应的启示对音乐列表进行排序。
public class Music implements Comparable<CriteriaList> {
private String genre, artist, album, titre, price, note;
// getters, setters
public int compareTo(CriteriaList list) {
boolean title, album, genre, artist, note;
title = !list.getTitle().isEmpty() && this.getTitre().equals(list.getTitle());
album = !list.getAlbum().isEmpty() && this.getAlbum().equals(list.getAlbum());
genre = !list.getGenre().isEmpty() && this.getGenre().equals(list.getGenre());
artist = !list.getArtist().isEmpty() && this.getArtist().equals(list.getArtist());
note = !list.getNote().isEmpty() && (Integer.parseInt(this.getNote()) >= Integer.parseInt(list.getNote()));
return ((title ? 1 : 0) + (album ? 1 : 0) + (genre ? 1 : 0) + (artist ? 1 : 0) + (note ? 1 : 0));
}
}
My function compareTo return the number of fields which match to the criteria list and test if input are not empty. 我的函数compareTo返回与条件列表匹配的字段数,并测试输入是否为空。
public class MusicProvider extends Agent {
public List<Music> getMusicsByCL(CriteriaList list) {
ArrayList<Music> res = new ArrayList<Music>();
int[] revelanceTab = new int[res.size()];
int i = 0, revelance;
for (Music music : musicListAvailable) {
revelance = music.compareTo(list);
if (revelance > 1) {
res.add(music);
revelanceTab[++i] = revelance;
}
}
// sort res with revelanceTab
return res;
}
}
Here I want to retrieve musics with a minimun revelance of 1 and sort them by revelance. 在这里,我要检索最小启示度为1的音乐,并按启示性对它们进行排序。 How can I do that ? 我怎样才能做到这一点 ?
Assuming you have already created the functionality to actually calculate the relevance, I would proceed like this. 假设您已经创建了实际计算相关性的功能,我将像这样继续进行。
Create a simple class to hold the Music and the calculated relevance score, just pass in the Criteria and store the result of the calculation. 创建一个简单的类来保存音乐和计算出的相关性分数,只需传递条件并存储计算结果即可。
public class ScoredMusic {
private int relevanceScore;
public ScoredMusic(Music m) { ... }
public void calculateRelevance(Criteria criteria) { ... }
public Music getMusic() { ... }
public int getRelevanceScore() { ... }
}
Then I would score all the Music instances you have, store them in a list, and do a very simple compareTo()
implementation that simply compares the relevanceScore
between each ScoredMusic
instance. 然后,我将比分你的所有音乐的情况下,将它们存储在一个列表中,并做了非常简单compareTo()
实现了简单的比较relevanceScore
每间ScoredMusic
实例。
Comparable is used to compare two instances of Music against each other. Comparable用于比较Music的两个实例。 If you want to compare to an external entity, use a Comparator implementation and pass it to Collections.sort(List, Comparator) . 如果要与外部实体进行比较,请使用Comparator实现并将其传递给Collections.sort(List,Comparator) 。 The Comparator would need to be initialized with the CriteriaList and the compare method would return a positive number if the first element should be ranked higher, negative number if the second element should be ranked higher, or 0 if they are equivalent. 比较器将需要使用CriteriaList进行初始化,如果第一个元素的排名较高,则compare方法将返回正数;如果第二个元素的排名较高,则compare方法将返回负数;如果等效,则返回0。 In your example, you would use your compareTo method and subtract the second element's score from the first and return that. 在您的示例中,您将使用compareTo方法并从第一个元素中减去第二个元素的分数,然后将其返回。
Something like this: 像这样:
import java.util.Comparator;
public class MusicComparator implements Comparator<Music> {
private final CriteriaList criteria;
public MusicComparator(CriteriaList criteria) {
this.criteria = criteria;
}
@Override
public int compare(Music o1, Music o2) {
return score(o1) - score(o2);
}
private int score(Music music) {
boolean title, album, genre, artist, note;
title = criteria.getTitle().isEmpty() || criteria.getTitle().equals(music.getTitle());
album = criteria.getAlbum().isEmpty() || criteria.getAlbum().equals(music.getAlbum());
genre = criteria.getGenre().isEmpty() || criteria.getGenre().equals(music.getGenre());
artist = criteria.getArtist().isEmpty() || criteria.getArtist().equals(music.getArtist());
note = criteria.getNote().isEmpty() || (!music.getNote().isEmpty() && Integer.parseInt(music.getNote()) >= Integer.parseInt(criteria.getNote()));
return ((title ? 1 : 0) + (album ? 1 : 0) + (genre ? 1 : 0) + (artist ? 1 : 0) + (note ? 1 : 0));
}
}
By the way, the isEmpty() methods will not protect you from null pointer exceptions. 顺便说一句,isEmpty()方法不会保护您免受空指针异常的影响。 You will need a better method of handling those if the fields are allowed to be null. 如果允许字段为空,则将需要一种更好的方法来处理这些字段。
This is my final class, 这是我的最后一堂课
public class ScoredMusic implements Comparable<ScoredMusic> {
private int revelanceScore = 0;
private Music music;
public ScoredMusic(Music music, CriteriaList crit) {
this.music = music;
calculateRevelance(crit);
}
private void calculateRevelance(CriteriaList list) {
boolean title, album, genre, artist, note;
title = !list.getTitle().isEmpty() && music.getTitre().equals(list.getTitle());
album = !list.getAlbum().isEmpty() && music.getAlbum().equals(list.getAlbum());
genre = !list.getGenre().isEmpty() && music.getGenre().equals(list.getGenre());
artist = !list.getArtist().isEmpty() && music.getArtist().equals(list.getArtist());
note = !list.getNote().isEmpty() && (Integer.parseInt(music.getNote()) >= Integer.parseInt(list.getNote()));
revelanceScore = ((title ? 1 : 0) + (album ? 1 : 0) + (genre ? 1 : 0) + (artist ? 1 : 0) + (note ? 1 : 0));
}
public Music getMusic() {
return music;
}
public int getRevelanceScore() {
return revelanceScore;
}
public int compareTo(ScoredMusic other) {
return Integer.compare(this.getRevelanceScore(), other.getRevelanceScore());
}
}
and in my second class 在我的第二堂课
public List<ScoredMusic> getMusicsScoredByCL(CriteriaList list) {
ArrayList<ScoredMusic> scoredMusics = new ArrayList<ScoredMusic>();
ScoredMusic sc;
for (Music music : musicListAvailable) {
sc = new ScoredMusic(music, list);
scoredMusics.add(sc);
}
// sort by revelance and descending order
Collections.sort(scoredMusics, Collections.reverseOrder());
return scoredMusics;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.