當前位置:編程學習大全網 - 源碼下載 - java 集合,泛型

java 集合,泛型

要點: ArrayList不是唯壹的集合

TreeSet以有序狀態保持並可防止重復

HashMap可用成對的name/value來保存與取出

LinkedList針對經常插入或刪除中間元素所設計的高效率集合

HashSet防止重復的集合,可快速地找尋相符的元素

LinkedHashMap類似HashMap,但可以記住元素插入的順序,也可以設定成依照元

素上次存取的先後來排序

可以使用TreeSet或Collections.sort()方法來排序

ArrayList是最常用的泛型化類型,有兩個關鍵部分:類的聲明和新增元素的方

法的聲明

Sort()方法只能接受Comparable對象的list

Collections.sort()會把list中的String依照字母排序

以泛型的觀點來說,extend代表extend or implement,代表“是壹個。。。”

,且適用於類和接口

調用單壹參數的sort(List o)方法代表由list元素上的comparetTo()方法來決定

順序。因此元素必須要實現Comparable這個接口

調用sort(List o,Comparator c)方法代表不會調用list元素的compareTo()方法

,而會使用Comparator的compare()方法,這意味著list元素不需要實現Comparable.

LIST:是壹種索引位置的集合

SET:註重獨壹無二的性質,不允許重復的集合

MAP:使用成對的鍵值和數據值,值可重復,但KEY不可

如果foo與bar兩對象相等,則foo.equals(bar)會返回true,且兩者的hashCode()

也會返回相同的值。要讓Set能把對象視為重復的,就必須讓它們符合上面的條件。

hashCode()與equals()的相關規定:

1)如果兩個對象相等,則hashcode必須也是相等的。

2)如果兩個對象相等,對其中壹個對象調用equals()必須返回true。也就是說

,若a.equals(b)則b.equals(a).

3)如果對象有相同的hashcode值,它們也不壹定是相等的。但若兩個對象相等

,則hashcode值壹定是相等的。

4)因此若equals()被覆蓋過,則hashcode()也必須被覆蓋。

5)hashcode()的默認行為是對在heap上的對象產生獨特的值.妳沒有override過

hashcode(),則該class的兩個對象怎樣都不會被認為是相同的。

6)equals()的默認行為是執行==的比較。也就是說會去測試兩個引用是否對

上heap上同壹個對象。如果equals()沒有被覆蓋過,兩個對象永遠都不會被視為相同的,

因為不同的對象有不同的字節組合。

a.equals()必須與a.hashCode()==b.hashCode()等值。

但a.hashCode()==b.hashCode()不壹定要與a.equals()等值。

要使用TreeSet,下列其中壹項必須為真:

TreeSet集合中的元素必須是有實現Comparable的類型

使用重載、取用Comparator參數的構造函數來創建TreeSet.

MAP中的元素實際上是兩個對象,關鍵字和值。值可以重復,但是關鍵字不可。

如果方法的參數是Animal的數組,它也能夠取用Animal次類型的數組。

也就是說,如果方法是這樣聲明的:void foo(Animal[] a){}

若Dog有extend過Animal,妳就可以用下列的兩種方式調用:

foo(anAnimalArray);

foo(aDogArray);

數組的類型是在運行期間檢查的,但集合的類型檢查只會發生在編譯期間

在方法參數中使用萬用字符時,編譯器會阻止任何可能破壞引用參數所指集合的

行為。妳能夠使用list中任何元素的方法,但不能加入元素。也就是說,妳可以操作集合

元素,但不能新增集合元素。如此才能保障執行期間的安全性,因為編譯器會阻止執行期

的恐怖行動。所以下面這個程序是可以的:

for(Animal a:animals){

a.eat();

}

但這個就過不了編譯:

animals.add(new Cat());

--------------------

程序代碼:

=========================================

SongList.txt

----------------------------------

Communication/The Cardingans

Black Dog/Led Zeppelin

Dreams/Van Halen

Comfortably Numb/Pink Floyd

Beth/Kiss

倒退嚕/黃克林

=========================================

記錄KTV最常點的歌,沒有排序功能

import java.util.*;

import java.io.*;

public class Jukebox1{

//歌曲名稱存在String的ArrayList上

ArrayList<String> songList= new ArrayList<String>();

public static void main(String[] args){

new Jukebox1.go();

}

//這個方法會載入文件並列出內容

public void go(){

getSongs();

System.out.println(songList);

}

//讀取文件的程序

void getSongs(){

try{

File file=new File("SongList.txt");

BufferedReader reader=new BufferedReader(new

FileReader(file));

String line=null;

while(line=reader.readLine())!=null){

addSong(line);

}

}catch(Exception ex){ex.printStackTrace();}

}

void addSong(String lineToParse){

//split()方法會用反斜線來拆開歌曲內容

String[] tokens=lineToParse.split("/");

//因為只需要歌名,所以只取第壹項加入SongList

songList.add(tokens[0]);

}

}

====

//依照加入的順序列出,與原始的文本文件順序相同。

輸出:

%java Jukebox1

[Communication,Black Dog,Dreams,Comfortably Numb,Beth,倒退嚕]

-----------------------------------------------------------------

對點歌系統加上Collections.sort()

import java.util.*;

import java.io.*;

public class Jukebox1{

//歌曲名稱存在String的ArrayList上

ArrayList<String> songList= new ArrayList<String>();

public static void main(String[] args){

new Jukebox1.go();

}

//這個方法會載入文件並列出內容

public void go(){

getSongs();

System.out.println(songList);

Collections.sort()(songList);

System.out.println(songList);

}

//讀取文件的程序

void getSongs(){

try{

File file=new File("SongList.txt");

BufferedReader reader=new BufferedReader(new

FileReader(file));

String line=null;

while(line=reader.readLine())!=null){

addSong(line);

}

}catch(Exception ex){ex.printStackTrace();}

}

void addSong(String lineToParse){

//split()方法會用反斜線來拆開歌曲內容

String[] tokens=lineToParse.split("/");

//因為只需要歌名,所以只取第壹項加入SongList

songList.add(tokens[0]);

}

}

====

輸出:

%java Jukebox1

[Communication,Black Dog,Dreams,Comfortably Numb,Beth,倒退嚕]

[Beth,Black Dog,Comfortably Numb,Communication,Dreams,倒退嚕]

-------------------------------------------------------------

現在要用song對象而不只是string

class Song{

//對應四種屬性的四個實例變量

String title;

String artist;

String rating;

String bpm;

Song(String t, String a,String r,String b){

//變量都會在創建時從構造函數中設定

title=t;

artist=a;

rating=r;

bpm=b;

}

//四種屬性的getter

public String getTitle(){

retrun title;

}

public String getArtist(){

retrun artist;

}

public String getRating(){

retrun rating;

}

public String getBpm(){

retrun bpm;

}

//將toString()覆蓋過,讓它返回歌名

public String toString(){

return title;

}

}

=========================================

SongList.txt

----------------------------------

Communication/The Cardingans/5/80

Black Dog/Led Zeppelin/4/84

Dreams/Van Halen/6/20

Comfortably Numb/Pink Floyd/5/110

Beth/Kiss/4/100

倒退嚕/黃克林/5/90

=========================================

說明:新的歌曲文件帶有四項屬性,所以我們需要創建出Song的實例變量來帶這些屬性。

修改點歌系統程序

import java.util.*;

import java.io.*;

public class Jukebox1{

//將String改成Song類型

ArrayList<Song> songList= new ArrayList<Song>();

public static void main(String[] args){

new Jukebox1.go();

}

//這個方法會載入文件並列出內容

public void go(){

getSongs();

System.out.println(songList);

Collections.sort()(songList);

System.out.println(songList);

}

//讀取文件的程序

void getSongs(){

try{

File file=new File("SongList.txt");

BufferedReader reader=new BufferedReader(new

FileReader(file));

String line=null;

while(line=reader.readLine())!=null){

addSong(line);

}

}catch(Exception ex){ex.printStackTrace();}

}

void addSong(String lineToParse){

//split()方法會用反斜線來拆開歌曲內容

String[] tokens=lineToParse.split("/");

//使用解析出來 的四項屬性來創建Song對象並加入到list中

Song nextSong =new Song(tokens[0],tokens[1],tokens[2],tokens[3]);

songList.add(nextSong);

}

}

====

輸出:

%javac Jukebox3.java

Jukebox3.java:15:cannot find symbol

symbol :method sort(java.util.ArrrayList<Song>)

location:class java.util.Collections

Collections.sort(songList);

1 error

關於泛型

1)創建被泛型化類的實例

創建ArrayList時妳必須要指定它所容許的對象。

new ArrayList<Song>()

2)聲明與指定泛型類型的變量

List<Song> songList = new ArrayList<Song>()

3)聲明(與調用)取用泛型類型的方法

void foo(List<Song> list)

x.foo(songList)

---------------------------------------------

ArrayList的類型參數

下面這行程序:

ArrayList<String> thisList = new ArrayList<String>

代表這個ArrayList:

public class ArrayList<E> extends AbstractList<E>...{

public boolean add(E o)

//更多代碼

}

會被編譯器這樣看待:

public class ArrayList<String> extends AbstractList<String>...{

public boolean add(String o)

//更多代碼

}

-------------------------------------------------------------------

運用泛型的方法

1)使用定義在類聲明的類型參數。

public class ArrayList<E> extends AbstractList<E>...{

public boolean add(E o)

}

2)使用未定義在類聲明的類型參數

//<T extends Animal> 為方法聲明的壹部分,表示任何被聲明為Animal或Animal的子型

public <T extends Animal> void takeThing(ArrayList<T> list)

//public void takeThing(ArrayList<Animal> list)表示只有ArrayList<Animal>合法。

-----------------------------------------------------------------------------

public static <T extends Comparable<? super T>> void sort(List<T> list)

//T extends Comparable表示它必須是Comparable

//? super T表示Comparable的類型參數必須是T或T的父型

//List<T>表示僅能傳入繼承Comparable的參數化類型的list

-----------------------------------------------------------------------------

class Song implements Comparable<Song>{

//對應四種屬性的四個實例變量

String title;

String artist;

String rating;

String bpm;

//Song s為要比較的對象

public int compareTo(Song s){

return title.compareTo(s.getTitle());

}

Song(String t, String a,String r,String b){

//變量都會在創建時從構造函數中設定

title=t;

artist=a;

rating=r;

bpm=b;

}

//四種屬性的getter

public String getTitle(){

retrun title;

}

public String getArtist(){

retrun artist;

}

public String getRating(){

retrun rating;

}

public String getBpm(){

retrun bpm;

}

//將toString()覆蓋過,讓它返回歌名

public String toString(){

return title;

}

}

====

調用sort()方法後會把Song依照字母作排序

輸出:

%java Jukebox3

[Communication,Black Dog,Dreams,Comfortably Numb,Beth,倒退嚕]

[Beth,Black Dog,Comfortably Numb,Communication,Dreams,倒退嚕]

---------------------------------------------------------------

用Comparator更新點歌系統

我們在新版本做了三件事:

1)創建並實現Comparator的內部類,以compare()方法取代compareTo()方法

2)制作該類的實例

3)調用重載版的sort(),傳入歌曲的list以及Comparator的實例。

import java.util.*;

import java.io.*;

public class Jukebox5{

//將String改成Song類型

ArrayList<Song> songList= new ArrayList<Song>();

public static void main(String[] args){

new Jukebox5.go();

}

//創建江實現Comparator的內部類,註意到類型參數和要比較的類型是相符的

//one.getArtist()會返回String,compareTo以String來比較

class ArtistCompare implements Comparator<Song>{

public int compare(Song one,Song two){

return one.getArtist().compareTo(two.getArtist());

}

}

//這個方法會載入文件並列出內容

public void go(){

getSongs();

System.out.println(songList);

Collections.sort()(songList);

System.out.println(songList);

//創建Comparator的實例,調用sort(),傳入list與Comparator對象

ArtistCompare artistCompare = new ArtistCompare();

Collections.sort(songList,artistCompare);

System.out.println(songList);

}

//讀取文件的程序

void getSongs(){

try{

File file=new File("SongList.txt");

BufferedReader reader=new BufferedReader(new

FileReader(file));

String line=null;

while(line=reader.readLine())!=null){

addSong(line);

}

}catch(Exception ex){ex.printStackTrace();}

}

void addSong(String lineToParse){

//split()方法會用反斜線來拆開歌曲內容

String[] tokens=lineToParse.split("/");

//使用解析出來 的四項屬性來創建Song對象並加入到list中

Song nextSong =new Song(tokens[0],tokens[1],tokens[2],tokens[3]);

songList.add(nextSong);

}

}

-----------------------------------------------------------------

以HashSet取代ArrayList

import java.util.*;

import java.io.*;

public class Jukebox6{

ArrayList<Song> songList= new ArrayList<Song>();

public static void main(String[] args){

new Jukebox6.go();

}

public void go(){

//這個方法沒有更新,所以它還是會把Song加到ArrayList中

getSongs();

System.out.println(songList);

Collections.sort()(songList);

System.out.println(songList);

//創建參數化的HashSet來保存Song,addAll()可以復制其他集合的元素

HashSet<Song> songSet = new HashSet<Song>();

songSet.addAll(songList);

System.out.println(songSet);

}

//getSongs() and addSong() methods

}

-------------------------------------------------------------------

有覆蓋過hashCode()與equals()的Song類

class Song{

String title;

String artist;

String rating;

String bpm;

//Object aSong為要比較的對象

public boolean equals(Object aSong){

Song s = (Song) aSong;

//因為歌名是String,且String本來就喜笑顏開過的equals(),所以我們可調用

return getTitle().equals(s.getTitle());

}

public int hashCode(){

//String也有覆蓋過的hashCode(),註意到hashCode()與

//equals()使用相同的實例變量

return title.hashCode();

}

public int compareTo(Song s){

return title.compareTo(s.getTitle());

}

Song(String t, String a,String r,String b){

//變量都會在創建時從構造函數中設定

title=t;

artist=a;

rating=r;

bpm=b;

}

//四種屬性的getter

public String getTitle(){

retrun title;

}

public String getArtist(){

retrun artist;

}

public String getRating(){

retrun rating;

}

public String getBpm(){

retrun bpm;

}

//將toString()覆蓋過,讓它返回歌名

public String toString(){

return title;

}

}

-----------------------------------------------------------

如果想要保持有序,使用TreeSet

import java.util.*;

import java.io.*;

public class Jukebox8{

ArrayList<Song> songList= new ArrayList<Song>();

int val;

public static void main(String[] args){

new Jukebox8.go();

}

public void go(){

getSongs();

System.out.println(songList);

Collections.sort()(songList);

System.out.println(songList);

//調用沒有參數的構造函數來用TreeSet取代HashSet意味著

//以對象的compareTo()方法來進行排序

TreeSet<Song> songSet = new TreeSet<Song>();

//使用addAll()可以把對象全部加入

songSet.addAll(songList);

System.out.println(songList);

}

//讀取文件的程序

void getSongs(){

try{

File file=new File("SongList.txt");

BufferedReader reader=new BufferedReader(new

FileReader(file));

String line=null;

while(line=reader.readLine())!=null){

addSong(line);

}

}catch(Exception ex){ex.printStackTrace();}

}

void addSong(String lineToParse){

//split()方法會用反斜線來拆開歌曲內容

String[] tokens=lineToParse.split("/");

//使用解析出來 的四項屬性來創建Song對象並加入到list中

Song nextSong =new Song(tokens[0],tokens[1],tokens[2],tokens[3]);

songList.add(nextSong);

}

}

-----------------------------------

public <T extends Animal> void takeThing(ArrayList<T> list)

public void takeThing(ArrayList<? extends Animal>list)是壹樣的~

  • 上一篇:外賣小哥跑腿送酒被騙上百元,這是怎麽回事?
  • 下一篇:Apache Flink快速入門-基本架構、核心概念和運行流程
  • copyright 2024編程學習大全網