集合的使用
概念
集合:存儲對象的容器,面向對象語言對事物的體現都是以對象的形式,所以為了方便對多個對象的操作,存儲對象,集合是存儲對象最常用的一種方式。
集合的出現就是為了持有對象。集合中可以存儲任意類型的對象, 而且長度可變。在程序中有可能無法預先知道需要多少個對象,
那么用數組來裝對象的話, 長度不好定義, 而集合解決了這樣的問題。
array: 存放統一數據類型的容器. 但由于array的空間在創建時就固定了,無法隨元素的變化而變化,所以array比較浪費空間.而且array可以存放多種數據類型,可能導致所存放的類型不統一.
集合和數組的區別
數組和集合類都是容器
數組長度是固定的,集合長度是可變的。數組中可以存儲基本數據類型,集合只能存儲對????象數
組中存儲數據類型是單一的,集合中可以存儲任意類型的對象。
集合類的特點
用于存儲對象,長度是可變的,可以存儲不同類型的對象。
集合的結構:
collection 接口 根接口? 集合的公共方法都在這個接口中
List 接口? 可以有重復的元素,并且元素的順序是有序的
Set 接口? 不可以有重復的元素且元素是無無序的
使用集合的目的:使數據的增刪改查更加容易
先來看collection的使用? 由于接口無法創建對象,就需要用實現類(如ArrayList)來創建
Collection col = new ArrayList();
添加: 1.col.add(object); 若object是基本數據類型則會轉換成相應的包裝對象
2.col.addAll(col1);將一個集合添加到另一個集合中去 自動追加到后面
刪除:
1.col.remove(object);刪除指定對象
2.col.removeAll(col1);刪除指定集合中的元素
3.col.clear();清空集合
判斷:
col.isEmpty();判斷集合是否為空
col.contains(object);判斷集合中是否存在指定元素
contains 方法最終會調用對象的equals 方法? 如有必要 可以重寫equals方法記得??????還要重寫hashCode 方法
col.containsAll(col1);判斷是否包含另外一集合col1;
col.retainAll(col1) ;僅保留與指定集合的交集元素,刪除其他元素
獲取:
col.size();獲取當前集合的大小
轉換數組:
col.toArray();將集合轉換成數組 返回一個對象數組
當需要遍歷集合時,可以先將集合轉換成數組,再進行遍歷.
List 接口中特有的方法
List list = new ArrayList();
1.增:
list.add(object);
list.add(object1);
list.add(1,object2);將對象添加到指定的位置
2獲取:
list.get(index); 獲取指定索引位置元素
3.查:
list.indexOf(object);返回所要查找元素在集合中第一次出現的位置,如果沒找到?????????就返回-1;
list.lastIndexOf(object);返回所要查找元素在集合中最后一次出現的位置,如果沒找到?????????就返回-1;
4.刪:
list.remove(list.size() - 1); 刪除最后一個元素;刪除指定索引位置元素
5.改:
list.set(index,object);更改指定索引位置元素
list.subList(begIndex,endIndex);通過指定索引范圍,返回一個新的集合
比起Collection? List 集合中特有的方法
都是通過下標來進行操作的
ArrayList:底層維護了一個數組(Object[]默認長度是10),增刪較慢,查找較快
元素在內存中是有序的,因此查找就比較快
若是默認容量(10)不夠,就增加到原來的1.5倍.
ArrayList 特有的方法:
ensureCapacity(int minCapacity) 手動調整容量
trimToSize();? 調整集合容量 使其容量與元素個數相同
LinkedList:增刪元素較快,查找較慢 元素在內存中保存是無序的,所以查找較慢
LinkedList 的使用:
LinkedList list = new LinkedList();
list.addFirst(object); 添加對象到最前
list.addLast(object);添加對象到最后
迭代器
定義:用來操作集合中的元素,增刪,獲取集合中的對象.
Iterator:迭代器的超級接口,所有的迭代器接口都是繼承與Iterator
常用方法:
hasNext();? 正序判斷列表中是否還有元素
Collection c = new
ArrayList();
Iterator it = c.iterator;
獲取相應集合的迭代器;
it.hasNext();,如果next 返回一個元素而不是拋出異常,則返回 true
next();返回下一元素,迭代器下移? 可以用來遍歷集合
while(it.hasNext()){
System.out.println(it.next());
}
迭代器類似于一根指針指向集合中第一個元素,每調用一次next(),迭代器就下移一位
remove();
it.remove(); 移除最后一次操作的元素
ListIterator? 繼承與Iterator 擁有其中的方法
特有方法:
List list = new ArrayList();
.//添加元素
ListIterator it = list.ListIterator();
it.hasPrevious(); 如果previous 返回一個元素,就返回true
it.previous();返回上一元素,迭代器上移一位
it.previousIndex(); 返回上一元素的索引
it.add(object) ; 在當前迭代器指向位置添加元素
it.set(object);替換當前迭代器指向位置元素
迭代器使用注意事項:
當使用迭代器來操作集合中的元素時,不要再用集合來操作了
LinkedList中特有的方法
增:
LinkedList
list? = new LinkedList();
list.addFirst(object);將對象添加到集合最前面
list.addLast(object);將對象添加到集合最后面
獲取:
list.getFirst();獲取第一個元素
list.getLast();獲取最后一個元素
移除:
list.removeFirst();移除第一個元素
list.removeLast();移除最后一個元素
如果集合中沒有元素,還進行移除和獲取的話
會拋出一個異常
數據結構:
堆棧
list.push(obj);向集合的堆棧中推入一個值
list.pop();從集合的堆棧中推出一個值
遵循先進后出原則
隊列
list.offer(obj);向隊列中添加一個值
list.poll();從隊列中移除一個值
遵循先進先出原則
獲取逆序迭代器:
Iterator
i = list.descendingIterator();
while(i.hasNext()){
System.out.println(i.next());
}
逆序遍歷
Vector:用來描述一個線程安全的ArrayList, 使用和ArrayList一樣
Vector 與 ArrayList 的區別:
相同點:底層都是通過object數組來實現的
不同點:
1.ArrayList
線程不同步,操作效率高
Vector 線程同步,操作效率低
2.ArrayList實在jdk1.2出現的,Vector
在1.0出現 (為了效率 ????????????????????????????????????????????推出ArrayList)
Set接口 繼承于Collection接口? 特點 : 元素無序且不能重復
HashSet
HashSet 的存儲原理:存在一個哈希表中,會調用對象的hashCode方法獲取哈希值
然后通過位移的運算 ,獲取一個哈希表的位置值
情況一:如果計算的位置上沒有任何元素,那么就將對象放在這個位置上
情況二:如果計算的位置上存在元素,這時就會將要存的對象
與其 做比較
就會調用equals方法
,如果返回的是true 就代表該對象是重復元素就不添加,
如果返回的是false
就添加該對象
子實現類??????????主要看HashSet? 與? TreeSet
HashSet set = new HashSet();//由于是無序的? 所以不能用索引獲取元素
set.add(object);返回一個布爾值,如果在集合內已經存在object那么就返回false,不存??????????在則添加該元素并返回true;
遍歷set (無序的):
1
.將集合轉換成數組在進行遍歷
2
.迭代器遍歷
TreeSet
特點:使用元素的自然順序對元素進行排序,底層使用二叉樹來實現
TreeSet
set = new TreeSet();
set.add(obj);會對對象進行一個自然排序;(ASCII
碼)
存儲的對象需要具備自然排序的特性(1
2 3 4 5 .....);
TreeSet注意點:
1.添加對象時,若是對象用有自然排序的特性,就進行自然排序
2.當所要添加的對象不具備自然排序的特性,就會拋出一個異常.
解決辦法:
1.實現Comparable
接口 并重寫 compareTo 方法;會返回???????????????????????????????????????????????????????一個負數,正數或者零
分別代表 小于 大于 等于
2.創建TreeSet對象時(構造方法),傳進去一個比較器
比較器定義方式:
class
類名 implementsCompartor{
}
當同時使用這兩種方法時,方法二生效
泛型:確定集合中只能存儲某一種類型的對象,java jadk1.5新特性
好處:
1.將運行時的錯誤提前到編譯時報出;
2.避免了無謂的強制類型轉換;
定義泛型方法:自定義泛型就是一個數據類型的占位或者說是一個數據類型變量,一般用T或E來做占位??????????????符(并不必要,只要滿足命名規范即可)
格式:
public static T 方法名(T s){
return
s;
}
方法泛型格式:<占位符>T;
注意點:
1.泛型方法中自定義一個泛型數據類型是在實際參數傳遞時才被確定的
2.泛型所用的標識符需要符合標識符的命名規范,一般習慣用大寫的字母表示
定義泛型類
格式 : class 類名 <聲明自定義的泛型>{}
注意點:
1.泛型類上定義的自定義泛型的類型是在創建對象時才確定的
2.如果一個自定義泛型的類,在創建對象時沒有指定泛型的類型,默認為object
3.靜態方法是不能夠使用類上自定義的泛型,只能在方法上聲明一個泛型
定義泛型接口:
格式:
interface
接口名 <聲明自定義泛型>{}
注意點:
1.接口上的自定義的泛型,是在實現該接口的時候實現的
2.如果實現該接口時沒有指定泛型,就會默認為object
3.需要在創建接口實現類對象時指定數據類型,那么需要格式:
class
類名<聲明自定義泛型> implements 接口<聲明自定義泛型>
Map集合
Map 接口? ? 雙列集合 K:V? ? 與OC中很像
特點: 儲存數據是以鍵和值的方式,鍵不允許重復,值是允許重復的.
子實現類:
HashMap;與HashSet原理相同,不過判斷的對象是鍵(不可重復)
TreeMap;與TreeMap原理相同,不過比較的對象是元素的鍵(自然排序)
HashTable;與HashMap
一樣,區別: 線程安全,效率慢
Map中常用方法:
Map
map = new HashMap();
添加:
map.put(K
key,V value);添加一個鍵值對
map.putAll(m);將m集合中的元素添加到本集合中
刪除:
claer();清空本集合
remove(object
key);通過鍵刪除元素
獲取:
get(object
key);通過鍵獲取元素
size();獲取集合大小(元素個數)
判斷:
map.isEmpty();
判斷集合是否為空
map.containsKey(key);判斷是否存在某個鍵
map.containsValue(value);判斷是否存在某個值
使用注意點:
1.Map
集合中鍵和值都可以是任意對象(不同于OC 鍵只能存字符串)
2.Map集合中是可以嵌套儲存list(Map)集合的
Map
遍歷
1.keySet();
返回Map中所有鍵,并用一個Set 來接收,通過遍歷鍵集合??????????????????????來遍歷Map
2.values();???????????獲取Map中所有得值
并用一個Collection 來接收
3.entry();Map.Entry
接口: 提供給用戶用來操作Map
Map.Entry
entry = map.entry();? 可以參照API資料
Collection: 集合的根接口
Collections: 集合的工具類? ? (如數組的工具類Arrays)
區別:
Collection
是一個單列集合的根接口
Collections是操作集合的工具類