java 集合類、排序和去重

一、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]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章