泛型应用 - 卡拉 OK(四)
文章来源:《Head First Java》修炼感悟。
上文说到,解决了按歌名排序的问题后,老白立刻想到了按歌手名字排序的问题。 老白决定趁热打铁,尝试着实现自定义排序方式。
Collections 的另一种排序
老白查看了 Collections 另一个排序方法的定义,对参与比较的对象没有强制实现 Comparable 接口的要求,意味着任何类都可以进行比较:
sort()
方法说明中指出,需要使用指定的比较器,即 Comparator 接口提供的 compare()
方法。 我们再来看看 比较器接口是如何定义的:
Comparator 接口说明中指出,能够为没有自然顺序的对象集合提供排序操作。 如此就可以实现各种各样的比较器,而不会像 compareTo()
方法只能将自己和另一个同类型对象进行比较。
自定义的 Song 比较器
了解了带比较器接口的排序方法后,老白现在需要做三件事情:
- 创建 Comparator 内部类,实现 compare() 方法用于比较;
- 创建 Comparator 比较器对象;
- 调用 Collections 带比较器接口的重载方法。
再次修改代码,版本编号 v5.0:
/**
* 文件:Karaoke5.java
*
* 描述:模拟 KTV 曲目清单,学习使用集合排序。
* 版本:v5.0
*/
import java.io.*;
import java.util.*;
public class Karaoke5 {
/**
* 用于对歌手名字进行比较的内部类,实现了Comparator接口
*/
class ArtistCompare implements Comparator<Song> {
// 对传入的Song对象的歌手名字的字符串进行比较
// 并返回一个整数值给 Collections 的比较方法
public int compare(Song one, Song two) {
return one.getArtist().compareTo(two.getArtist());
}
}
// 用来保存所有曲目的列表
ArrayList<Song> tracks = new ArrayList<Song>();
// 执行入口
public void go() {
loadSongs();
// 原始顺序
System.out.println("original: " + tracks);
// 按曲目排序
Collections.sort(tracks);
System.out.println("by title: " + tracks);
// 按歌手名字排序
ArtistCompare ac = new ArtistCompare();
Collections.sort(tracks, ac);
System.out.println("by artist: " + tracks);
}
// 载入曲目文件
private void loadSongs() {
try {
// 先不理会下面语句的含义,
// 只需知道能读取 songs.txt 文件内容就可以了
File file = new File("songs.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null) {
addSong(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 解析曲目
private void addSong(String token) {
String[] tokens = token.split("/");
Song s = new Song(tokens[0], tokens[1], tokens[2], tokens[3]);
tracks.add(s);
}
// 程序入口
public static void main(String[] args) {
new Karaoke5().go();
}
}
编译执行:
很不错,现在按歌名、按歌手都可以排序了。
新的问题接踵而至...
随着 KTV 营业时间越来越久,曲目中偶尔会出现重复歌曲或者歌手。 那么这种重复数据又该如何处理呢? 老白又闲不住了…
《 上一篇 泛型应用 - 卡拉 OK(三) |
---|