一、java集合類框架圖
二、集合的特點
三、集合的排序
方法一、集合元素實現Comparable泛型接口,重寫comparable方法
現有一個歌曲表單.txt,需要對其進行排序
雙截棍/周杰倫 五環之歌/岳雲鵬 Black/Pink Floyd/Numb Comfortable/Van Halen Breath/Kiss
1、先創建歌名實體類,
public class Song implements Comparable<Song>{
String title;
String artist;
public Song(String title, String artist) {
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 title;
}
/**
* 比較歌曲名
* @param song
* @return
*/
@Override
public int compareTo(Song song) {
return title.compareTo(song.getTitle());
}
}
2、測試
我們將需要排序的集合和自定義的排序類傳入Collections的sort()方法裏
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
public class Jukebox3
{
ArrayList<Song> songList = new ArrayList<>();
public static void main(String[] args)
{
new Jukebox3().go();
}
public void go()
{
getSong();
System.out.println(songList);
Collections.sort(this.songList); //調用Collections的sort()方法對集合進行排序
System.out.println(this.songList);
}
public void getSong()
{
File file = new File("E:\\java_project\\test\\src\\歌曲表單.txt");
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = bufferedReader.readLine()) != null)
{
addSong(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void addSong(String line) {
String[] tokes = line.split("/");
Song song = new Song(tokes[0],tokes[1]);
songList.add(song);
}
}
測試結果:可以看出按照字母順序進行了排序
[雙截棍, 五環之歌, Black, Floyd, Comfortable, Breath]
[Black, Breath, Comfortable, Floyd, 五環之歌, 雙截棍]
方法二、自定義comparator
這一次我們不需要實現Comparable泛型接口,重寫comparable方法。而是自定義一個comparator
1、創建歌曲類
public class Song {
String title;
String artist;
public Song(String title, String artist) {
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 title;
}
}
2、創建自定義排序類
import java.util.Comparator;
public class TitleCompare implements Comparator<Song> {
@Override
public int compare(Song o1, Song o2) {
return o1.getTitle().compareTo(o2.getTitle());
}
}
3、測試,我們將需要排序的集合和自定義的排序類傳入Collections的sort()方法裏
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
public class Jukebox3
{
ArrayList<Song> songList = new ArrayList<>();
public static void main(String[] args)
{
new Jukebox3().go();
}
public void go()
{
getSong();
System.out.println(songList);
//創建自定義排序
TitleCompare titleCompare = new TitleCompare();
Collections.sort(songList,titleCompare);
System.out.println(songList);
}
public void getSong()
{
File file = new File("E:\\java_project\\test\\src\\歌曲表單.txt");
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = bufferedReader.readLine()) != null)
{
addSong(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void addSong(String line) {
String[] tokes = line.split("/");
Song song = new Song(tokes[0],tokes[1]);
songList.add(song);
}
}
測試結果:同樣能完成排序
[雙截棍, 五環之歌, Black, Floyd, Comfortable, Breath]
[Black, Breath, Comfortable, Floyd, 五環之歌, 雙截棍]
四、集合的去重
集合去重的精髓在於首先判斷集合中兩個對象是否相等,如果相等才能去重
問題:對象怎樣纔算相等?
1、引用相等
引用到堆上同一個對象的兩個引用是相等的,這就是引用的相等性。
如果想要知道兩個引用是否相等,可以使用==來比較變量上的字節組合,如果引用到相同的對象,字節組合也會一樣:
if (foo == bar){ // 兩個引用都指向同一個對象 }
2、對象相等
堆上的兩個不同對象在意義上是相同的,這就是對象的相等性。
兩個對象相等的條件是它們的hashCode相等,而且調用以另一個對象爲參數的equals時返回true:
if (foo.equals(bar) && foo.hashCode() == bar.hashCode()) { // 兩個引用指向同一個對象或者兩個對象是相等的 }
我們知道所有的類都繼承自Object類,而Object類默認的equals方法是使用==進行比較:
public boolean equals(Object obj) { return (this == obj); }
Object類的hashCode函數:
public native int hashCode();
是一個native函數,而且返回值類型是整形;實際上,該native方法將對象在內存中的地址作爲哈希碼返回,可以保證不同對象的返回值不同。
因此,要比較兩個對象的相等性,首先需要重寫equals和hashCode方法。
下面我們重寫上面的例子,首先加入有重複的歌曲名單
雙截棍/周杰倫 五環之歌/岳雲鵬 Black/Pink Floyd/Numb Comfortable/Van Halen Breath/Kiss Breath/Kiss Breath/Kiss
1、重寫equals和hashCode方法
我們根據歌曲名判斷對象的相同,由於歌曲名是String類型的,實際上String類型重寫了Object的equals和hasCode方法,它是根據字符串內容比較相等。
public class Song {
String title;
String artist;
public Song(String title, String artist) {
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 title;
}
public boolean equals(Object song)
{
Song s = (Song) song;
return getTitle().equals(s.getTitle());
}
public int hashCode()
{
return title.hashCode();
}
}
2、使用Set進行去重
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
public class Jukebox3
{
ArrayList<Song> songList = new ArrayList<>();
public static void main(String[] args)
{
new Jukebox3().go();
}
public void go()
{
getSong();
System.out.println(songList);
//創建自定義排序
TitleCompare titleCompare = new TitleCompare();
Collections.sort(songList,titleCompare);
System.out.println(songList);
HashSet<Song> songSet = new HashSet<>();
songSet.addAll(songList);
System.out.println(songSet);
}
public void getSong()
{
File file = new File("E:\\java_project\\test\\src\\歌曲表單.txt");
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = bufferedReader.readLine()) != null)
{
addSong(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void addSong(String line) {
String[] tokes = line.split("/");
Song song = new Song(tokes[0],tokes[1]);
songList.add(song);
}
}
測試結果:我們可以看到加入HashSet的元素被去重了
[雙截棍, 五環之歌, Black, Floyd, Comfortable, Breath, Breath, Breath]
[Black, Breath, Breath, Breath, Comfortable, Floyd, 五環之歌, 雙截棍]
[Breath, 五環之歌, Floyd, 雙截棍, Black, Comfortable]