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]

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