Java面向對象筆記 • 【第7章 集合】

全部章節   >>>>


本章目錄

7.1 集合概述

7.1.1 Java集合體系概述

7.1.2 實踐練習

7.2 List集合

7.2.1 ArrayList實現類

7.2.2 LinkedList實現類

7.2.3 實踐練習(一)

7.2.4 實踐練習(二)

7.3 Set集合和Iterator迭代器

7.3.1 Set集合

7.3.2 Iterator迭代器

7.3.3 實踐練習

7.4 Map集合

7.4.1 Map集合

7.4.2 實踐練習

總結:


7.1 集合概述7

7.1.1 Java集合體系概述

爲了使程序方便地存儲和操縱數目不固定的一組數據,JDK類庫中提供了Java集合,所有Java集合類都位於java.util包中。與Java數組不同,Java集合不能存放基本數據類型,而只能存放對象

Java集合類主要由兩個接口派生而出,即CollectionMap接口。CollectionMapJava集合框架的最上層的父接口,這兩個接口又包含其他的子接口和實現類

Java集合主要包括三種類型: Set(集),List(列表)Map(映射) 

Collection集合體系的繼承樹

實線表示繼承關係,虛線表示實現關係

Map體系的繼承樹

Java集合的三種數據類型存儲示意圖

1、Set特點

類似於一個罐子,將一個對象添加到Set集合時,Set集合無法記住添加此元素的順序

Set集合中的元素是不能重複的,否則系統無法準確識別此元素

2、List特點

類似於一個數組,它可以記錄每個元素添加的順序,但List長度可變

3、Map特點

Map集合的存放方式,同樣類似於一個罐子,但Map集合中的每項數據都由兩個值組成它們分別爲keyvaluekey不可以重複,但是value可以重複。

 

Collection接口常用方法

方法名

說明

boolean add(Object obj)

向集合中添加一個元素

boolean addAll(Collection c)

將集合c的所有元素添加到指定集合中

void clear()

清除集合中的所有元素,此時集合長度變爲0

boolean contains(Object obj)

返回集合中是否包含指定的元素

boolean contains(Collection c)

返回集合中是否包含指定的c集合

Boolean  isEmpty()

判斷集合是否爲空。集合長度爲0時返回true,否則返回false

Iterator iterator()

返回一個Iterator對象,用於遍歷集合中的元素

boolean remove(Object obj)

刪除集合中的指定元素obj,當集合中包含一個或多個元素obj時,僅刪除第一個符合條件的元素

int  size()

返回集合中元素的個數

Object[] toArray()

將當前集合轉換成一個Object[]類型的數組

7.1.2 實踐練習

 

7.2 List集合

List集合代表一個元素是有序可以重複、可以爲null集合

集合中每個元素都有其對應的順序索引,List集合允許添加重複元素,可以通過索引來訪問指定位置的集合元素

List 的數據結構就是一個序列,存儲內容時直接在內存中開闢一塊連續的空間,然後將空間地址與索引對應。

List最常實現ArrayListLinkedList

 

Collection接口的所有方法之外List還擁有的其他方法

方法名

說明

void add(int index, Object element)

添加對象element到位置index

booleanaddAll(int index, Collection collection)

index位置後添加容器collection中所有的元素

Object get(int index)

取出下標爲index的位置的元素

intindexOf(Object element)

查找對象elementList中第一次出現的位置

intlastIndexOf(Object element)

查找對象elementList中最後出現的位置

Object remove(int index)

刪除index位置上的元素,並返回被刪除的這個元素

Object set(int index,Object element)

index位置上的所示對象替換爲element並返回被替換

7.2.1 ArrayList實現類

ArrayList是基於數組實現的List類,ArrayList底層是通過一個長度可變的數組實現的

ArrayList允許對元素進行快速的隨機訪問,但是向ArrayList中插入與刪除元素的速度較慢

示例: 演示ArrayList類使用方法

//創建ArrayList對象
ArrayList arrayList=new ArrayList();
arrayList.add("JAVA-DEMO");//向集合中添加字符串對象
arrayList.add(new Hero());//向集合中添加用戶自定義對象
System.out.println("arrayList集合的大小="+arrayList.size());
for(int i=0;i<arrayList.size();i++) //遍歷集合元素
	Object obj=arrayList.get(i); //按照下標獲取元素
boolean flag=arrayList.contains("JAVA-DEMO"); //是否包含字符串"JAVA-DEMO"
Object obj=arrayList.remove("JAVA-DEMO");//刪除指定元素字符串"JAVA-DEMO"
System.out.println("被刪除的元素="+obj);
arrayList.set(0, "ANDROID");//將集合下標爲0的元素修改爲ANDORID

7.2.2 LinkedList實現類

LinkedList類在實現時,採用鏈表數據結構,所以向LinkedList中插入和刪除元素的速度較快,隨機訪問速度則相對較隨機訪問是獲取指定下標位置的元素

LinkedList單獨具有addFirst()addLast()getFirst()getLast()removeFirst()removeLast()方法。這些方法使LinkedList可以作爲堆棧、隊列和雙向隊列來使用。

 

LinkedList常用方法

方法名

說明

void addFirst(Object o)

將指定元素o插入列表起始位置

addLast(Object o)

將指定元素o添加至列表末尾處

Object removeFirst()

移除並返回列表的首元素

Object removeLast()

移除並返回列表的首元素

示例:演示LinkedList類使用方法

LinkedList linkedList=new LinkedList();
ArrayList  ayList=new ArrayList();
ayList.add("JAVA-DEMO");
ayList.add('中');
//將ayList對象添加至linkedList集合中
linkedList.add(ayList);
//添加自定義類型對象
linkedList.add(new Hero());
linkedList.addFirst(99.8);//向集合頭部添加一個元素
Object obj=linkedList.removeFirst();//刪除頭部元素

示例:比較ArrayListLinkedList刪除元素的效率

ArrayList aList=new ArrayList(); //創建ArrayList集合
System.out.println("==========ArrayList==========");
long bTime=System.currentTimeMillis(); //獲取當前系統的時間(毫秒數表示)
System.out.println("起始時間:"+bTime);
for(int i=0;i<100000;i++)
	aList.add("DEMO"+i);//向集合中添加數據
int size=aList.size();
for(int i=0;i<size;i++)
	aList.remove(0);//每次都刪除集合中的第一個元素
long eTime=System.currentTimeMillis();
System.out.println("結束時間:"+eTime);
System.out.println("ArrayList添加、刪除所用時間="+(eTime-bTime)+"毫秒");
//創建LinkedList集合
LinkedList lList=new LinkedList();
...
System.out.println("LinkedList添加、刪除所用時間="+(edTime-bginTime)+"毫秒");

示例:比較ArrayListLinkedList訪問元素的效率

ArrayList aList=new ArrayList(); //創建ArrayList集合
System.out.println("==========ArrayList==========");
for(int i=0;i<100000;i++)
	aList.add("DEMO"+i);//向集合中添加數據
//獲取當前系統的時間(毫秒數表示)
long bTime=System.currentTimeMillis();
System.out.println("開始時間:"+bTime);
for(int i=0;i<1000000000;i++)
	aList.get(99999); //每次讀取列表末尾元素
long eTime=System.currentTimeMillis();
System.out.println("結束時間:"+eTime);
System.out.println("ArrayList隨機訪問所用時間="+(eTime-bTime)+"毫秒");
LinkedList lList=new LinkedList(); //創建LinkedList集合
System.out.println("==========LinkedList==========");
...
for(int i=0;i<1000000000;i++)
	lList.get(99999); //每次讀取列表末尾元素
...
System.out.println("LinkedList隨機訪問所用時間="+(edTime-bgTime)+"毫秒");

經驗:

 List就是一個線性表接口,而ArrayListLinkedList又是線性表的兩種典型實現,ArrayList   是基於數組的線性表,而LinkedList是基於鏈的線性表

當對集合元素進行頻繁的添加或刪除操作,使用LinkedList效率比較高,因爲鏈表的插入和刪除操作效率比較高。

當對集合元素進行頻繁讀取操作使用ArrayList效率比較高,因爲基於數組的線性表的隨機訪問效率比較高。

7.2.3 實踐練習(一)

7.2.4 實踐練習(二)

 

7.3 Set集合和Iterator迭代器

7.3.1 Set集合

Set集合,類似於一個瓶子,“裝進”Set集合中的多個對象之間沒有明顯的順序

Set集合不允許包含相同的元素,如果試圖將兩個相同的元素加入同一個Set集合中,則添加操作失敗返回false,且新元素不會被加入其集合中。

HashSetSet接口的最常用的實現類。HashSetHash算法實現存儲集合中的元素,因爲其具有良好的存儲和查找性能。

Set的排列順序可能與添加順序不同Set元素值可以是null

示例:添加Cat對象到HashSet集合

public class Cat { 
	private  String name;
	private  String color;
	…
	public  String toString(){ //重新toString()
		return "名字:"+this.name+"-"+"毛色:"+this.color;
	}
}
public class HashSetTest {
	 public  static void  useHashSet(){
		HashSet hs=new HashSet();
		 hs.add("JAVA");
		 hs.add(new Cat("加菲","黃色"));
		 hs.add(new Cat("湯姆","青色"));
		 hs.add(new Cat("加菲","黃色"));
		 hs.add("JAVA");//添加重複對象"JAVA"
		 hs.add(100);//添加重複對象"JAVA"
		 System.out.println("HashSet對象集合="+hs);
	 }
…..

 

提問:有兩條貓的名字和顏色一摸一樣,怎麼它們可以一起添加到Set集合?

分析:

這兩條貓的名字和顏色一摸一樣,但它們equals()返回值爲false,hashCode()值也不相等。所以這兩條貓不相同。

如果兩條貓相同的邏輯是它們名字和顏色相同,則可通過重寫Cat類的equals() 和hashCode() 。

 

示例:重寫Cat的equals() 和hashCode()

public  boolean  equals(Object obj){
	if(obj==this){
	    return true;
	}else{
		if(obj instanceof Cat){
			Cat  cat=(Cat)obj;
	        if(this.name.equals(cat.name) && this.color.equals(cat.color))
	    			return true;
	    	else
				return false;
	    }else
			return false;
	}
}	
//重寫hashCode()方法
public int hashCode(){
	return   this.name.hashCode()*this.color.hashCode();
}


重寫hashCode()方法的一般規則如下:

在程序運行時,同一個對象的hashCode()方法應該返回相同的值。

兩個對象通過equals()方法比較返回true時,這兩個對象的hashCode()方法應返回相等的值。

中用作equals()方法比較標準的屬性,都應該用於計算hashCode的值。

7.3.2 Iterator迭代器

Iterator接口隱藏了各種Collection實現類的底層細節,該接口提供了遍歷Collection集合元素的統一編程接口

迭代器是一種設計模式,它是一個對象,它可以遍歷並選擇序列中的對象,而開發人員不需要了解該序列的底層結構。迭代器通常被稱爲“輕量級”對象,因爲創建它的代價小。

由於Set集合中存儲的是無序的元素,因此無法在循環中按照下標獲取Set集合中的元素,所以利用Iterator接口遍歷Set集合中的元素尤爲方便。

 

Iterator常用方法

方法名

說明

boolean hasNext(Object o)

如果被迭代的集合中的元素沒有遍歷完成,則返回true

Object next()

返回集合中的下一個元素

Void remove()

將迭代器新返回的元素刪除

示例:Iterator迭代器應用案例

HashSet  hs=new HashSet();
hs.add(1);
hs.add(new Date());
hs.add("ANDORID");
hs.add(new Cat("加菲","粉色"));
//調用HashSet對象的iterator()方法,返回Iterator實例
Iterator it=hs.iterator();
//使用while循環,循環判斷迭代器中是否還有元素
System.out.println("====使用迭代器遍歷HashSet集合=====");
while(it.hasNext()){
	//獲取迭代器中的數據
	Object obj=it.next();
	System.out.println(obj);
}

7.3.3 實踐練習

 

7.4 Map集合

Map用於保存具有映射關係的數據Map集合中保存着兩組值,一組值用於保存Map裏的key,另外一組值保存Mapvaluekeyvalue可以爲null

keyvalue可以是任意類型的數據Mapkey不允許重複,即同一個Map對象的任何兩個key通過equals()方法比較總是返回false

keyvalue間存在單向一對一關係,即通過指定的key總能找到唯一的、確定的value。從Map中取出數據時,只要給出指定的key,就可以取出對應的value

HashMapMap接口最爲常用的實現類,HashMap通過哈希碼對其內部的映射關係進行快速查找。

7.4.1 Map集合

Map接口常用方法

方法名

說明

put(K key,V value)

向映射中添加一對keyvalue的映射關係

Object get(Object key)

返回映射中key所對應的value。如果該映射中不包含key,則返回null

putAll(Map  map)

將映射map所有的鍵值映射關係添加到當前映射

containsKey(Object key)

如果此映射包含指定鍵的映射關係,則返回true

containsValue(Object value)

如果此映射將一個或多個鍵映射到指定的value,則返回true

keySet()

將該集合中的所有鍵對象以Set集合的形式返回

values()

將該集合中的所有值對象以Collection集合的形式返回

remove(Object key)

如果存在指定的鍵key,則移除該鍵的映射關係,並返回與該鍵對象對應的值對象,否則返回null

clear()

從此映射中移除所有映射關係

isEmpty()

如果此映射未包含鍵-值映射關係,則返回true

size()

返回此映射中的鍵-值映射關係的數量

示例:HashMap應用案例

Map hm=new HashMap();
hm.put("JAVA", "DEMO");
hm.put("中國", "北京");
hm.put(1, "one");
hm.put(true,"正確" );
hm.put("中國", "上海");
System.out.println("========HashMap集合添加元素後=======");
System.out.println(hm);
System.out.println("====按照Kye獲取對應Value值====");
Object value=hm.get("中國");
System.out.println("key值爲中國對應的value值="+value);
System.out.println("HashMap集合的大小="+hm.size());
System.out.println("===遍歷HashMap集合===");
//返回存儲HashMap集合中的所有的key(鍵)的Set集合
Set set=hm.keySet();
Iterator it=set.iterator();//返回key集合的Iterator迭代器
while(it.hasNext()){//遍歷key
	Object key=it.next();//得到HashMap集合中的key值
	Object  val=hm.get(key);//通過key得到對應的value值
	System.out.println("鍵="+key+"\t"+"值="+val);
}

HashMapHashtable的區別

HashMap

Hashtable

允許出現空值、空鍵

不允許出現空值、空鍵

線程異步,效率較高

線程同步,效率較低

繼承自AbstractMap

繼承自Dictionary

7.4.2 實踐練習

 

總結:

  • 所有Java集合類都位於java.util包中。與Java數組不同,Java集合不能存放基本數據類型,而只能存放對象
  • Java集合類主要由兩個接口派生而出,即CollectionMap接口。CollectionMapJava集合框架的最上層的父接口,這兩個接口又包含其他的子接口和實現類
  • List集合代表一個元素是有序的、且可以重複的、可以爲null的集合。可以通過get(int index)取出下標爲index的元素
  • List最常見的實現類是ArrayListLinkedList。當對集合元素進行頻繁的讀取操作時,使用ArrayList效率比較高;當對集合元素進行頻繁的添加或刪除操作時,使用LinkedList效率比較高
  • Set集合不允許包含相同的元素,Set的排列順序可能與添加順序不同,Set元素值可以是nullHashSetSet接口的最常用的實現類。可以通過重寫類的equals()hashCode()方法定義對象相等的邏輯
  • Iterator迭代器提供了遍歷Collection集合元素的統一編程接口
  • Map用於保存具有映射關係的數據。Map集合中保存着兩組值,一組值用於保存Map裏的key,另外一組值保存Mapvaluekeyvalue可以爲null
  • Map接口的put(K key,V value)用於向映射中添加一對keyvalue的映射關係,get(Object key)用於返回映射中key所對應的value

 

 

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