一 集合
一、集合框架的組成:
二、集合概述
1.背景:面嚮對象語言對事物的體現都是以對象的形式,所以爲了方便對多個對象的操作,就對對象進行存儲,集合就是存儲對象最常用的一種方式。
2.與數組的不同: 數組雖然也可以存儲對象,但長度是固定的;集合長度是可變的。數組中可以存儲基本數據類型,集合只能存儲對象。
3.特點: 集合只用於存儲對象,集合長度是可變的,集合可以存儲不同類型的對象。
二 Collection
其下有兩個子接口:List(列表),Set(集)
(一)、Collection接口中的常見操作
1、添加元素
add(Objectobj); //add方法的參數類型是Object。
2、刪除元素
remove(Objectobj);
removeAll(另一集合);//調用者只保留另一集合中沒有的元素。
clear();//清空集合
3、判斷元素
contains(Objectobj);//判斷是否存在obj這個元素
isEmpty();//是否爲空
4、獲取個數,集合長度
size();
5、取交集
retainAll(另一集合);//調用者只保留兩集合的共性元素。
(二)、迭代
1、概述
迭代是取出集合中元素的一種方式。
對於集合的元素取出這個動作:
當不足以用一個函數來描述,需要用多個功能來體現,所以就將取出這個動作封裝成一個對象來描述。就把取出方式定義在集合的內部,這樣取出方式就可以直接訪問集合內部的元素。那麼取出方式就被定義成了內部類。
而每一個容器的數據結構不同,所以取出的動作細節也不一樣。但是都具有共性內容: 判斷和取出。那麼就可以將這些共性抽取。
那麼這些內部類都符合一個規則(或者說都抽取出來一個規則)。該規則就是Iterator。通過一個對外提供的方法:iterator();,來獲取集合的取出對象。
因爲Collection中有iterator方法,所以每一個子類集合對象都具備迭代器。
2、迭代的常見操作
hasNext();//有下一個元素,返回真
next();//取出下一個元素
remove();//移除
注:在迭代時循環中next調用一次,就要hasNext判斷一次。
使用:
ArrayList a=newArrayList();//創建一個集合
Iterator it=a.iterator();//獲取一個迭代器,用於取出集合中的元素。
第一種打印方式:
for(Iterator iter = a.iterator();iter.hasNext(); )
{
System.out.println(iter.next());
}
第二種打印方式:
Iteratoriter = a.iterator();
while(iter.hasNext())
{
System.out.println(iter.next());
}
3、迭代注意事項
- 迭代器在Collcection接口中是通用的,它替代了Vector類中的Enumeration(枚舉)。
- 迭代器的next方法是自動向下取元素,要避免出現NoSuchElementException。
- 迭代器的next方法返回值類型是Object,所以要記得類型轉換。
三 List
(一)、List
組成
List:元素是有序的,元素可以重複。因爲該集合體繫有索引。
ArrayList:底層的數據結構使用的是數組結構。特點:查詢速度很快。但是增刪稍慢。線程不同步。
LinkedList:底層使用的是鏈表數據結構。特點:增刪速度很快,查詢稍慢。
Vector:底層是數組數據結構。線程同步。被ArrayList替代了。
(二)、List的特有方法
凡是可以操作角標的方法都是該體系特有的方法。
1、增
booleanadd(index,element);//指定位置添加元素
BooleanaddAll(index,Collection);//在指定位置增加給定集合中的所有元素,若省略位置參數,則在當前集合的後面依次添加元素
2、刪
Booleanremove(index);//刪除指定位置的元素
3、改
set(index,element);//修改指定位置的元素。
4、查
get(index);//通過角標獲取元素
subList(from,to);//獲取部分對象元素
5、其他
listIterator();//List特有的迭代器
indexOf(obj);//獲取元素第一次出現的位置,如果沒有則返回-1
注:List集合判斷元素是否相同,移除等操作,依據的是元素的equals方法。
(三)、ListIterator
1、概述
ListIterator是List集合特有的迭代器,是Iterator的子接口。
在迭代時,不可以通過集合對象的方法操作集合中的元素。因爲會發生ConcurrentModificationException異常。所以在迭代器時,只能用迭代器的方法操作元素。可是Iterator方法是有限的,只能對元素進行判斷,取出,刪除的操作。如果想要其他的操作,如添加、修改等,就需要使用其子接口:ListIterrator。該接口只能通過List集合的ListIterator方法獲取。
2、ListIterator特有的方法
add(obj);//增加
set(obj);//修改爲obj
hasPrevious();//判斷前面有沒有元素
previous();//取前一個元素
(四)、Enumeration
枚舉:
就是Vector特有的取出方式。Vector有三種取出方式。
其實枚舉和迭代是一樣的。因爲枚舉的名稱以及方法的名稱都過長。所以被迭代器取代了。
特有方法:
addElement(obj);//添加元素,相當於add(obj);
Enumerationelements();//Vector特有取出方式(枚舉)
hasMoreElements();//相當於Iterator的hasNext()方法
nextElements();//相當於Iterator的next()方法
(五)、LinkedList
LinkedList:底層使用的是鏈表數據結構。特點:增刪速度很快,查詢稍慢。
特有方法:
1、增
addFirst();
addLast();
2、獲取
//獲取元素,但不刪除元素。如果集合中沒有元素,會出現NoSuchElementException
getFirst();
getLast();
3、刪
//獲取元素,並刪除元素。如果集合中沒有元素,會出現NoSuchElementException
removeFirst();
removeLast();
四 Set
(一)、概述
Set:元素是無序(存入和取出的順序不一定一致),元素不可以重複。
HashSet:底層數據結構是哈希表。線程不同步。 保證元素唯一性的原理:判斷元素的hashCode值是否相同。如果相同,還會繼續判斷元素的equals方法,是否爲true。
TreeSet:可以對Set集合中的元素進行排序。默認按照字母的自然排序。底層數據結構是二叉樹。保證元素唯一性的依據:compareTo方法return 0。
Set集合的功能和Collection是一致的。
(二)、HasSet
HashSet:線程不安全,存取速度快。
可以通過元素的兩個方法,hashCode和equals來完成保證元素唯一性。如果元素的HashCode值相同,纔會判斷equals是否爲true。如果元素的hashCode值不同,不會調用equals。
注意:HashSet對於判斷元素是否存在,以及刪除等操作,依賴的方法是元素的hashCode和equals方法。
(三)、TreeSet
1、特點
a、底層的數據結構爲二叉樹結構(紅黑樹結構)
b)可對Set集合中的元素進行排序,是因爲:TreeSet類實現了Comparable接口,該接口強制讓增加到集合中的對象進行了比較,需要複寫compareTo方法,才能讓對象按指定需求(如人的年齡大小比較等)進行排序,並加入集合。
java中的很多類都具備比較性,其實就是實現了Comparable接口。
注意:排序時,當主要條件相同時,按次要條件排序。
c、保證數據的唯一性的依據:通過compareTo方法的返回值,是正整數、負整數或零,則兩個對象較大、較小或相同。相等時則不會存入。
2、Tree排序的兩種方式
1)第一種排序方式:自然排序
讓元素自身具備比較性。元素需要實現Comparable接口,覆蓋compareTo方法。這種方式也被稱爲元素的自然順序,或者叫做默認順序。
2)第二種方式:比較器
當元素自身不具備比較性時,或者具備的比較性不是所需要的。這時就需要讓集合自身具備比較性。
在集合初始化時,就有了比較方式。定義一個比較器,將比較器對象作爲參數傳遞給TreeSet集合的構造函數。
比較器構造方式:定義一個類,實現Comparator接口,覆蓋compare方法。
當兩種排序都存在時,以比較器爲主。
五 Map集合
(一)、概述
1、簡述:
Map<K,V>集合是一個接口,和List集合及Set集合不同的是,它是雙列集合,並且可以給對象加上名字,即鍵(Key)
2、特點:
1)該集合存儲鍵值對,一對一對往裏存
2)要保證鍵的唯一性。
(二)、Map集合的子類
Map
Hashtable:底層是哈希表數據結構,不可以存入null鍵null值。該集合是線程同步的。
HashMap:底層是哈希表數據結構。允許使用null鍵null值,該集合是不同步的。
TreeMap:底層是二叉樹數據結構。線程不同步。可以用於給Map集合中的鍵進行排序。
Map和Set很像。其實Set底層就是使用了Map集合。
(三)、Map集合的常用方法
1、添加
Vput(K key,V value);//添加元素,如果出現添加時,相同的鍵,那麼後添加的值會覆蓋原有鍵對應值,並put方法會返回被覆蓋的值。
voidputAll(Map <? extends K,? extends V> m);//添加一個集合
2、刪除
clear();//清空
Vremove(Object key);//刪除指定鍵值對
3、判斷
containsKey(Objectkey);//判斷鍵是否存在
containsValue(Objectvalue)//判斷值是否存在
isEmpty();//判斷是否爲空
4、獲取
Vget(Object key);//通過鍵獲取對應的值
size();//獲取集合的長度
Collection<V>value();//獲取Map集合中所以得值,返回一個Collection集合
還有兩個取出方法,接下來會逐個講解:
Set<Map.Entry<K,V>>entrySet();
Set<K> keySet();
注:HashMap集合可以通過get()方法的返回值來判斷一個鍵是否存在,通過返回null來判斷。
(四)、Map集合的兩種取出方式
Map集合的取出原理:將Map集合轉成Set集合。再通過迭代器取出。
1、Set<K> keySet():將Map中所以的鍵存入到Set集合。因爲Set具備迭代器。所以可以通過迭代方式取出所以鍵的值,再通過get方法。獲取每一個鍵對應的值。
2、Set<Map.Entry<K,V>> entrySet():將Map集合中的映射關係存入到Set集合中,而這個關係的數據類型就是:Map.Entry
其實,Entry也是一個接口,它是Map接口中的一個內部接口。 關於Map.Entry:
Map是一個接口,其實,Entry也是一個接口,它是Map的子接口中的一個內部接口,就相當於是類中有內部類一樣。爲何要定義在其內部呢?
原因:a、Map集合中村的是映射關係這樣的兩個數據,是先有Map這個集合,纔可有映射關係的存在,而且此類關係是集合的內部事務。
b、並且這個映射關係可以直接訪問Map集合中的內部成員,所以定義在內部。