1、相同点:都是用来实现集合中元素大小的比较。
2、不同点:
1)Comparable采用的是内部比较法(本身有默认的比较规则),而Comparator属于外部比较法(一个外部的比较器,开发人员可以实现定义的比较规则)。
2)采用Comparable比较时,集合中的元素必须实现Comparable接口(比如String和Integer),使用的比较方法是:int compareTo(T o);
3)采用Comparator比较时,使用的比较方法是:int compare(T o1 ,T o2);
4)Comparable位于java.lang包中(无需导入),而Comparator位于java.util包中(需要导入)。
3、实例一:String类型元素的比较(采用Comparable)
package com.linwei;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class StringComparable {
public static void main(String[] args) {
//String类已实现Comparable接口
//public final class String implements java.io.Serializable, Comparable<String>, CharSequence(){}
List<String> sList =new ArrayList<String>();
sList.add("aa");
sList.add("bb");
sList.add("dd");
sList.add("cc");
sList.add("gg");
sList.add("ee");
System.out.println("排序前:"+sList);
// 使用Collections中的sort(List<T> list)方法实现排序功能
// public static <T extends Comparable<? super T>> void sort(List<T> list){}
/*
* extends :在泛型中表示继承或实现
* T extends Comparable:说明T类型必须实现Comparable接口
* <? super T> :说明List中泛型的类型必须为T类型或其子类型
* */
Collections.sort(sList);
System.out.println("排序后:"+sList);
}
}
执行输出:
排序前:[aa, bb, dd, cc, gg, ee]
排序后:[aa, bb, cc, dd, ee, gg]
4、实例二:对自定义对象进行排序(使用Comparable实现)
需求场景:实现KTV歌曲的排序功能(根据歌曲名称)
代码如下:
package com.linwei;
import java.util.ArrayList;
import java.util.Collections;
public class KTVComparable {
private ArrayList<Song> songList=new ArrayList<Song>();
public ArrayList<Song> getSongList() {
return songList;
}
public void setSongList(ArrayList<Song> songList) {
this.songList = songList;
}
public void go(){
System.out.println("排序前:"+songList);
Collections.sort(songList);
System.out.println("排序后:"+songList);
}
public static void main(String[] args) {
KTVComparable box=new KTVComparable();
Song song =new Song("aaa","xxx");
Song song2 =new Song("bbb","yyy");
Song song3 =new Song("ccc","zzz");
box.getSongList().add(song2);
box.getSongList().add(song);
box.getSongList().add(song3);
box.go();
}
}
/**
* 待排序的类必须实现Comparable接口
*/
class Song implements Comparable<Song> {
private String title; // 歌名
private String artist; // 歌手
public Song(String title,String artist) {
super();
this.title = title;
this.artist = artist;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String toString() {
return title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
//覆写Comparable接口中的对象比较方法,比较当前对象与传入对象的大小
public int compareTo(Song s) {
//根据歌名进行排序(采用默认的排序方法)
return title.compareTo(s.getTitle());
}
}
5、实例三:对自定义对象进行排序(使用Comparator实现)
需求场景:实现KTV歌曲的排序功能(根据歌曲名称及歌手名称进行排序)
代码如下:
package com.linwei;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class KTVComparator {
private ArrayList<Song2> songList=new ArrayList<Song2>();
public ArrayList<Song2> getSongList() {
return songList;
}
public void setSongList(ArrayList<Song2> songList) {
this.songList = songList;
}
public void go(){
System.out.println("排序前:"+songList);
// 需要传入自定义的比较器对象
Collections.sort(songList,new SongCompare());
System.out.println("排序后:"+songList);
}
public static void main(String[] args) {
KTVComparator box=new KTVComparator();
Song2 song =new Song2("aaa","xxx");
Song2 song2 =new Song2("bbb","yyy");
Song2 song3 =new Song2("bbb","ddd");
Song2 song4 =new Song2("eee","nnn");
box.getSongList().add(song2);
box.getSongList().add(song);
box.getSongList().add(song3);
box.getSongList().add(song4);
box.go();
}
}
/**
* 无需实现任何特定的排序接口
*/
class Song2 {
private String title;
private String artist;
public Song2(String title,String artist) {
super();
this.title = title;
this.artist = artist;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
@Override
public String toString() {
return "Song2 [title=" + title + ", artist=" + artist + "]";
}
}
/**
* 自定义的比较器(实现Comparator接口)
*/
class SongCompare implements Comparator<Song2>{
// 覆写Comparator中的比较方法
//先按歌名排序,如果 歌名相同,则再按歌手名排序
public int compare(Song2 s1, Song2 s2) {
if(s1.getTitle().compareTo(s2.getTitle()) <0){
return -1 ;
}else if(s1.getTitle().compareTo(s2.getTitle()) >0){
return 1 ;
}else if(s1.getTitle().compareTo(s2.getTitle()) ==0){
return s1.getArtist().compareTo(s2.getArtist());
}else{
return 0;
}
}
}
执行输出:
排序前:[Song2 [title=bbb, artist=yyy], Song2 [title=aaa, artist=xxx], Song2 [title=bbb, artist=ddd], Song2 [title=eee, artist=nnn]]
排序后:[Song2 [title=aaa, artist=xxx], Song2 [title=bbb, artist=ddd], Song2 [title=bbb, artist=yyy], Song2 [title=eee, artist=nnn]]
6、题外补充:关于Collections中的sort()方法的两个重载版本
1) public static <T extends Comparable<? super T>> void sort(List<T> list) {} :代表由List元素上的compareTo()方法来决定顺序,因此该元素必须实现Comparable接口。
2)public static <T> void sort(List<T> list, Comparator<? super T> c) {}:代表不会调用到List元素的compareTo()方法,而会使用Comparator中的compare()方法,因此该元素无需实现Comparable接口。