1. 程式人生 > >Java程式設計入門筆記(十一)

Java程式設計入門筆記(十一)

海納百川——物件陣列和集合

物件陣列

陣列 在Java提供的儲存及隨機訪問物件序列的各種方法中,陣列是效率最高的一種

  • 型別檢查
  • 邊界檢查

優點

  • 陣列知道其元素的型別
  • 編譯時的型別檢查
  • 大小已知

代價

  • 陣列物件的大小是固定的,在生存期內大小不可變

物件陣列

  • 陣列元素是類的物件
  • 所有元素具有相同的型別
  • 每個元素都是一個物件的引用

靜態初始化:在宣告和定義陣列的同時對陣列元素進行初始化,例如:

BankAccount[] accounts = { 
                new BankAccount(“Zhang", 100.00), 
                new BankAccount
(“Li", 2380.00), new BankAccount(“Wang", 500.00), new BankAccount(“Liu", 175.56), new BankAccount(“Ma", 924.02)};

動態初始化:使用運算子new,需要經過兩步: 首先給陣列分配空間

type arrayName[ ]=new type[arraySize];

然後給每一個數組元素分配空間

arrayName[0]=new type(paramList);
…
arrayName[arraySize-1]
=new type(paramList);

Java集合框架

  • 程式設計師不需要關心你的陣列到底該申請多少個元素,框架會自動幫你分配空間
  • 程式設計師可以通過一個鍵,快速得到這個鍵所對應的值,並且不需要顧慮插入和刪除元素的問題
  • 程式設計師可以方便地對資料進行排序、遍歷等
  • 程式設計師可以直接使用各種資料結構

Java集合框架提供了一套效能優良、使用方便的介面和類,它們位於java.util包中

CollectionListSetArrayListLinkedListHashSetTreeSetMapHashMapTreeMapCollections提供了對集合進行排序,遍歷等多種演算法實現

Collection 介面儲存一組不唯一,無序的物件

List 介面儲存一組不唯一,有序(插入順序)的物件

Set 介面儲存一組唯一,無序的物件

Map介面儲存一組鍵值物件,提供key(唯一)到value的對映

List類集合

ListArrayListLinkedList

ArrayList實現了長度可變的陣列,在記憶體中分配連續的空間。遍歷元素和隨機訪問元素的效率比較高

LinkedList採用連結串列儲存方式(離散空間)。插入、刪除元素時效率比較高

List介面常用方法小結 在這裡插入圖片描述 LinkedList的特殊方法 在這裡插入圖片描述 插入元素對比 在這裡插入圖片描述

隨機訪問對比 在這裡插入圖片描述

Vector類

  • 另外一個常用的列表類是Vector類,它也實現了List介面,可以實現ArrayList的所有操作。

  • Vector和ArrayList的異同

    • 實現原理、功能相同,可以互用
    • 主要區別 Vector執行緒安全操作相對較慢 ArrayList重速度輕安全,執行緒非安全 長度需增長時,Vector預設增長一倍,ArrayList增長50% Vector可以使用capacity()方法獲取實際的空間

ArrayList和Vector的預設初始大小均為10

Set類集合

如果確定元素在列表中不能重複,那麼可以使用Set Set無法隨機訪問,要訪問其元素,只能使用迭代器遍歷

SetHashSetTreeSet

Set支援的操作

  • boolean add(E e);
  • void clear();
  • boolean contains(Object o);
  • boolean isEmpty();
  • boolean remove(Object o);
  • int size();

HashSet:保證在Set中的元素唯一,但是不保證元素的順序恆久不變(加入新元素後,元素的遍歷順序可能發生改變)。

TreeSet:保證Set中的元素唯一,並且對元素按其自然順序進行排序。

  • TreeSet特有的操作:

    • E first();
    • E last();
    • E ceiling(E e);
    • E floor(E e);
    • E lower(E e);
    • E higher(E e);
    • void poolFirst();
    • void poolLast();

對比

HashSet TreeSet
保證元素唯一 保證元素唯一
元素在集合中的順序不定(並且和放入順序無關) 保證元素排序
使用equals()方法和hashCode()方法來保證元素唯一性 通過對元素比較判斷其結果是否為0來保證元素唯一性 元素可以實現Comparable介面也可以使用Comparator來比較元素
低層資料結構:雜湊連結串列 低層資料結構:二叉樹

演算法

Java中的演算法都封裝在類Arrays和Collections中

排序(Sorting) 使用Arrays.sort()方法可以對陣列進行排序

使用Collections.sort()方法可以對集合進行排序

排序演算法:

  • 當處理原始資料型別時,演算法為快速排序
  • 當處理物件型別時,演算法為歸併排序

亂序(Shuffling) 亂序就是做和排序相反的工作,將資料隨機地打亂順序。

生活中的亂序:洗牌。

常規資料處理演算法 reverse:將一個List中的元素反向排列

fill:用指定的值覆寫List中的每一個元素,這個操作在重新初始化List時有用

copy::接受兩個引數,目標List和源List,將源中的元素複製到目標,覆寫其中的內容。目標List必須至少與源一樣長,如果更長,則多餘的部分內容不受影響

查詢演算法binarySearch 使用二分法在一個有序的List中查詢指定元素 有兩種形式

  • 第一種形式假定List是按照自然順序升序排列的
  • 第二種形式需要增加一個Comparator物件,表示比較規則,並假定List是按照這種規則排序的。

尋找最值——用於任何集合物件 min和max演算法返回指定集合中的最小值和最大值 這兩個演算法分別都有兩種形式 簡單形式按照元素的自然順序返回最值 另一種形式需要附加一個Comparator物件作為引數,並按照Comparator物件指定的比較規則返回最值

Map類集合

Map介面專門處理鍵值對映資料的儲存,可以根據鍵實現對值的操作 最常用的實現類是HashMap

例子

 Map countries = new HashMap();
 countries.put("CN", "中華人民共和國");
 countries.put("RU", "俄羅斯聯邦");
 countries.put("FR", "法蘭西共和國");
 countries.put("US", "美利堅合眾國");
 //使用HashMap儲存多組鍵值對
 		
 String country = (String) countries.get("CN");
 //獲取指定元素的值
		
 System.out.println("Map中共有"+countries.size() +"組資料");
 //獲取Map元素個數
		
 countries.remove("FR");
 System.out.println("Map中包含FR的key嗎?" + countries.containsKey("FR"));
 //刪除指定元素,判斷是否包含指定元素
		
 System.out.println( countries.keySet() ) ;
 System.out.println( countries.values() );
 System.out.println( countries );
 //顯示鍵集、值集和鍵值對集

Map介面常用方法

查詢方法

方法名 說明
int size() 返回Map中的元素個數
boolean isEmpty() 返回Map中是否包含元素,如不包括任何元素,則返回true
boolean containsKey(Object key) 判斷給定的引數是否是Map中的一個關鍵字(key)
boolean containsValue(Object val) 判斷給定的引數是否是Map中的一個值(value)
Object get(Object key) 返回Map中與給定關鍵字相關聯的值(value)
Collection values() 返回包含Map中所有值(value)的Collection物件
Set keySet() 返回包含Map中所有關鍵字(key)的Set物件
Set entrySet() 返回包含Map中所有項的Set物件

修改方法

方法名 說明
Object put(Object key, Object val) 將給定的關鍵字(key)/值(value)對加入到Map物件中。其中關鍵字(key)必須唯一,否則,新加入的值會取代Map物件中已有的值
void putAll(Map m) 將給定的引數Map中的所有項加入到接收者Map物件中
Object remove(Object key) 將關鍵字為給定引數的項從Map物件中刪除
void clear() 從Map物件中刪除所有的項

雜湊表 也稱為散列表,是用來儲存群體物件的集合類結構,其兩個常用的類是HashTable及HashMap

雜湊表相關的一些主要概念

名詞 說明
容量(capacity) 雜湊表的容量不是固定的,隨物件的加入,其容量可以自動擴充
關鍵字/鍵(key) 每個儲存的物件都需要有一個關鍵字key,key可以是物件本身,也可以是物件的一部分(如物件的某一個屬性)
雜湊碼(hash code) 要將物件儲存到HashTable,就需要將其關鍵字key對映到一個整型資料,稱為key的雜湊碼(hash code)
雜湊函式(hash function) 返回物件的雜湊碼
項(item) 雜湊表中的每一項都有兩個域:關鍵字域key及值域value(即儲存的物件)。key及value都可以是任意的Object型別的物件,但不能為空(null),HashTable中的所有關鍵字都是唯一的
裝填因子(load factor) (表中填入的項數)/(表的容量)

構造方法

  • Hashtable( ); // 初始容量為101,最大裝填因子為0.75
  • Hashtable(int capacity);
  • Hashtable(int capacity, float maxLoadFactor);

雜湊表常用函式

方法名 說明
Object put(Object key, Object value) 值value以key為其關鍵字加入到雜湊表中,如果此關鍵字在表中不存在,則返回null,否則表中儲存的value
Object get(Object key) 返回關鍵字為key的值value,如果不存在,則返回null。
Object remove(Object key) 將鍵/值對從表中去除,並返回從表中去除的值,如果不存在,則返回null。
boolean isEmpty() 判斷雜湊表是否為空
boolean containsKey(Object key) 判斷給定的關鍵字是否在雜湊表中
boolean contains(Object value) 判斷給定的值是否在雜湊表中
boolean containsValue(Object value) 判斷給定的值是否在雜湊表中
void clear() 將雜湊表清空
Enumeration elements() 返回包含值的Enumeration物件
Enumeration keys() 返回包含關鍵字的Enumeration物件

HashMap類與HashTable類很相似,只是HashTable類不允許有空的關鍵字,而HashMap類允許

HashMap和Hashtable的比較 實現原理、功能相同,可以互用 主要區別

  • Hashtable繼承Dictionary類,HashMap實現Map介面
  • Hashtable執行緒安全,HashMap執行緒非安全
  • Hashtable不允許null值,HashMap允許null值

不涉及到多執行緒的開發過程中,最好使用ArrayList和HashMap 如果程式中用到多執行緒,酌情使用Vector和Hashtable

集合遍歷與迭代器(Iterator)

如何遍歷List, Set和Map集合呢? 方法1:迴圈(僅適用於List) 方法2:增強型for迴圈(foreach迴圈,適用於所有類) 方法3:通過迭代器Iterator實現遍歷

  • 獲取Iterator :Collection 介面的iterate()方法
  • Iterator的方法 boolean hasNext(): 判斷是否存在另一個可訪問的元素 Object next(): 返回要訪問的下一個元素

方法4:(僅適用於JDK 1.8) 適用forEach()方法

Iterator介面 也是一個遍歷集合元素的工具,是對Enumeration介面的改進,因此在遍歷集合元素時,優先選用Iterator介面

與Enumeration不同,具有從正在遍歷的集合中去除物件的能力

具有如下三個例項方法,可見相對於Enumerationo介面簡化了方法名

  • hasNext() —— 判斷是否還有元素
  • next() —— 取得下一個元素
  • remove() —— 去除一個元素。注意是從集合中去除最後呼叫
  • next()返回的元素,而不是從Iterator類中去除

遍歷Map例項

Set keys=dogMap.keySet();    //取出所有key的集合
Iterator it=keys.iterator();       //獲取Iterator物件
while(it.hasNext()){
	String key=(String)it.next();      //取出key
	Dog dog=(Dog)dogMap.get(key);    //根據key取出對應的值
	System.out.println(key+"\t"+dog.getStrain());
}
//迭代器Iterator
///////////////////////////////////////////////////
for(元素型別t  元素變數x : 陣列或集合物件){
         引用了x的java語句
}
//增加for型迴圈
///////////////////////////////////////////////////
Set keys=dogMap.keySet();
Keys.forEach(new DogConsumer());	//新建一個匿名物件

class DogConsumer implements Consumer {
	public void accept(Object obj) {	//每個Set中的物件,都會呼叫一次該方法
	}
}
//JDK 1.8 之後可以使用forEach方法遍歷集合

Enumeration Enumeration介面不能用於ArrayList物件,而Iterator介面既可以用於ArrayList物件,也可以用於Vector物件

Enumeration介面 (1.0版) 提供了兩個例項方法

  • hasMoreElements() —— 判斷是否還有剩下的元素;
  • nextElement() —— 取得下一個元素。

遍歷集合類物件v中的每個元素可使用下面程式碼完成:

Enumeration e = v.elements(); 
while (e.hasMoreElements()) { 
   Customer c = (Customer)v.nextElement(); 
   System.out.println(c.getName()); 
}