Java 使用关联比较器对列表进行排序
Java sort a list with revelance comparator
我正在尝试按符合标准列表的相关度对音乐列表进行排序。
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));
}
}
我的函数 compareTo return 匹配条件列表的字段数并测试输入是否为空。
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;
}
}
在这里,我想检索最小关联度为 1 的音乐,并按关联度对它们进行排序。我该怎么做?
Comparable 用于比较两个 Music 实例。如果要与外部实体进行比较,请使用 Comparator 实现并将其传递给 Collections.sort(List, Comparator)。 Comparator 需要用 CriteriaList 初始化,如果第一个元素应该排名更高,compare 方法将 return 为正数,如果第二个元素应该排名更高,则为负数,如果它们相等,则为 0。
在您的示例中,您将使用 compareTo 方法并从第一个和 return 中减去第二个元素的分数。
像这样:
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));
}
}
顺便说一下,isEmpty() 方法不会保护您免受空指针异常的影响。如果字段允许为空,您将需要一种更好的方法来处理这些问题。
假设您已经创建了实际计算相关性的功能,我会这样做。
创建一个简单的class来保存音乐和计算出的相关性分数,只需传入Criteria并存储计算结果。
public class ScoredMusic {
private int relevanceScore;
public ScoredMusic(Music m) { ... }
public void calculateRelevance(Criteria criteria) { ... }
public Music getMusic() { ... }
public int getRelevanceScore() { ... }
}
然后我会给你所有的 Music 实例打分,将它们存储在一个列表中,然后做一个非常简单的 compareTo()
实现,简单地比较每个 ScoredMusic
实例之间的 relevanceScore
.
这是我的决赛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());
}
}
在我的第二个 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;
}
我正在尝试按符合标准列表的相关度对音乐列表进行排序。
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));
}
}
我的函数 compareTo return 匹配条件列表的字段数并测试输入是否为空。
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;
}
}
在这里,我想检索最小关联度为 1 的音乐,并按关联度对它们进行排序。我该怎么做?
Comparable 用于比较两个 Music 实例。如果要与外部实体进行比较,请使用 Comparator 实现并将其传递给 Collections.sort(List, Comparator)。 Comparator 需要用 CriteriaList 初始化,如果第一个元素应该排名更高,compare 方法将 return 为正数,如果第二个元素应该排名更高,则为负数,如果它们相等,则为 0。 在您的示例中,您将使用 compareTo 方法并从第一个和 return 中减去第二个元素的分数。
像这样:
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));
}
}
顺便说一下,isEmpty() 方法不会保护您免受空指针异常的影响。如果字段允许为空,您将需要一种更好的方法来处理这些问题。
假设您已经创建了实际计算相关性的功能,我会这样做。
创建一个简单的class来保存音乐和计算出的相关性分数,只需传入Criteria并存储计算结果。
public class ScoredMusic {
private int relevanceScore;
public ScoredMusic(Music m) { ... }
public void calculateRelevance(Criteria criteria) { ... }
public Music getMusic() { ... }
public int getRelevanceScore() { ... }
}
然后我会给你所有的 Music 实例打分,将它们存储在一个列表中,然后做一个非常简单的 compareTo()
实现,简单地比较每个 ScoredMusic
实例之间的 relevanceScore
.
这是我的决赛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());
}
}
在我的第二个 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;
}