1. Collection集合框架java
Java.util.Collection接口算法
|--List子接口編程
|--ArrayList實現類數組
|--LinkedList實現類數據結構
|--Vector實現類框架
|--Stack(棧,繼承Vector,先進後出)ide
|--Set子接口
工具
|--HashSet實現類性能
|--TreeSet實現類spa
|--Queue接口(普通隊列,先進先出)
|--Deque子接口(雙端隊列)
|--ArrayDeque實現類
2. 泛型
1)泛型是 JDK1.5引入的新特性,泛型的本質是參數化類型。在類、接口、方法的定義過程當中,所操做的數據類型爲傳入的指定參數類型。全部的集合類型都帶有泛型參數,這樣在建立集合時能夠指定放入集合中的對象類型。同時,編譯器會以此類型進行檢查。
2)ArrayList支持泛型,泛型尖括號裏的符號可隨便些,但一般大寫E。
3)迭代器也支持泛型,可是迭代器使用的泛型應該和它所迭代的集合的泛型類型一致!
4)泛型只支持引用類型,不支持基本類型,但可使用對應的包裝類
5)若是泛型不指定類型的話,默認爲Object類型。
案例6:
3. List接口和Set接口
1)List接口:List接口是Collection的子接口,用於定義線性表數據結構,元素可重複、有序的;能夠將List理解爲存放對象的數組,只不過其元素個數能夠動態的增長或減小。
(1) List接口的兩個常見的實現類:ArrayList和LinkedList,分別用動態數組和鏈表的方式實現了List接口。List、ArrayList和LinkedList均處於java.util包下。
(2) 能夠認爲ArrayList和LinkedList的方法在邏輯上徹底同樣,只是在性能上有必定的差異,ArrayList更適合於隨機訪問,而LinkedList更適合於插入和刪除,在性能要求不是特別苛刻的情形下能夠忽略這個差異。
(3) 使用List咱們不須要在建立的時候考慮容量集合的容量是根據其所保存的元素決定的換句話說,集合的容量是能夠自動擴充的。
(4) List的實現類會重寫toString方法,依次調用所包含對象的toString方法,返回集合中所包含對象的字符串表現 。
2)Set接口:Set接口是Collection的子接口,用於存儲不重複的元素,元素是無序的。
(1) HashSet和TreeSet是Set集合的兩個常見的實現類,分別用hash表和排序二叉樹的方式實現了Set集合。HashSet是使用散列算法實現Set的。
(2) Set集合沒有get(int index)方法,咱們不能像使用List那樣,根據下標獲取元素。想獲取元素須要使用Iterator。
(3) 向集合添加元素也使用add方法,可是add方法不是向集合末尾追加元素,由於無序。
4. ArrayList實現類的經常使用方法
(1) add(Object obj):向想集合末尾追加一個新元素,從該方法的參數定義不難看出,集合能夠存聽任意類型的元素,但在實際編程中咱們發現,幾乎不會向集合中存放一種以上的不一樣類型的元素。
(2) size()方法:返回當前集合中存放對象的數量。
(3) clear()方法:用於清空集合。
(4) isEmpty()方法:用於返回集合是否爲空。
案例7:
(5) contains(Object obj)方法:檢查給定對象是否被包含在集合中,檢查規則是將obj對象與集合中每一個元素進行equals比較,若比對了全部元素均沒有equals爲true的則返回false。注意事項:根據狀況重寫equals:若比較是不是同一個對象,則不須要重寫,直接用contains裏的equals比較便可。若重寫equals爲內容是否相同,則按內容比較,不論是否同一個對象。是否重寫元素的equals方法對集合的操做結果有很大的效果不一樣!
(6) boolean remove(Object obj)方法:刪除一個元素,不重寫equals,不會有元素被刪除(由於比較的是對象的地址,都不相同),重寫equals爲按內容比較,則刪除第一個匹配的就退出,其餘即便內容相同也不會被刪除。
(7) Object remove(int index)方法:移除此列表中指定位置上的元素。向左移動全部後續元素(將其索引減1)。所以在作刪除操做時集合的大小爲動態變化的,爲了防止漏刪,必須從後往前刪!
(8) Object get(int index)方法:根據元素下標獲取對應位置的元素並返回。
(9) Object set(int index,Object newElement)方法:將index位置的元素修改成newElement,修改後將被修改的元素返回。可實現將List中第i個和第j個元素交換的功能:list.set ( i , list.set ( j , list.get ( i ) ) ) ;
(10) add(int index,Object newElement)方法:使用add的重載方法,咱們能夠向index指定位置插入newElement,原位置的元素自動向後移動,即所謂的「插隊」。
(11) Object[] toArray()方法:該方法繼承自Collection的方法,該方法會將集合以對象數組的形式返回。
(12) List<E> subList(int fromIndex, int toIndex)方法:獲取子集合,但在獲取子集後,若對子集合的元素進行修改,則會影響原來的集合。
5. HashSet實現類經常使用經常使用方法
(1) boolean add(E e) :若是此 set 中還沒有包含指定元素,則添加指定元素。
(2) void clear() :今後 set 中移除全部元素。
(3) Object clone() :返回此 HashSet 實例的淺表副本:並無複製這些元素自己。
(4) boolean contains(Object o) :若是此 set 包含指定元素,則返回 true。
(5) boolean isEmpty() :若是此 set 不包含任何元素,則返回 true。
(6) Iterator<E> iterator(): 返回對此 set 中元素進行迭代的迭代器。
(7) boolean remove(Object o): 若是指定元素存在於此 set 中,則將其移除。
(8) int size() :返回此 set 中的元素的數量(set 的容量)。
注意事項:
1)hashCode對HashSet的影響:若咱們不重寫hashCode,那麼使用的就是Object提供的,而該方法是返回地址(句柄)!換句話說,就是不一樣的對象,hashCode不一樣。
2)對於重寫了equals方法的對象,強烈要求重寫繼承自Object類的hashCode方法的,由於重寫hashCode方法與否會對集合操做有影響!
3)重寫hashCode方法須要注意兩點:①與equals方法的一致性,即equals比較返回爲true的對象其hashCode方法返回值應該相同(優肯不一樣)。②hashCode返回的數值應該符合hash算法要求,若是有不少對象的hashCode方法返回值都相同,則會大大下降hash表的效率。通常狀況下,可使用IDE(如Eclipse)提供的工具自動生成hashCode方法。
4)boolean contains(Object o)方法:查看對象是否在set中被包含。下例雖然有新建立的對象,可是經過散列算法找到了位置後,和裏面存放的元素進行equals比較爲true,因此依然認爲是被包含的(重寫equals了時)。
5)HashCode方法和equals方法都重寫時對hashSet的影響:將兩個對象同時放入HashSet集合,發現存在,再也不放入(不重複集)。當咱們重寫了Point的equals方法和hashCode方法後,咱們發現雖然p1和p2是兩個對象,可是當咱們將他們同時放入集合時,p2對象並無被添加進集合。由於p1在放入後,p2放入時根據p2的hashCode計算的位置相同,且p2與該位置的p1的equals比較爲true, hashSet認爲該對象已經存在,因此拒絕將p2存入集合。
案例8:
6)不重寫hashCode方法,可是重寫了equals方法對hashSet的影響:兩個對象均可以放入HashStet集合中,由於兩個對象具備不用的hashCode值,那麼當他們在放入集合時,經過hashCode值進行的散列算法結果就不一樣。那麼他們會被放入集合的不一樣位置,位置不相同,HashSet則認爲它們不一樣,因此他們能夠所有被放入集合。
7)重寫了hashCode方法,可是不重寫equals方法對hashSet的影響:在hashCode相同的狀況下,在存放元素時,他們會在相同的位置,hashSet會在相同位置上將後放入的對象與該位置其餘對象一次進行equals比較,若不相同,則將其存入在同一個位置存入若干元素,這些元素會被放入一個鏈表中。由此能夠看出,咱們應該儘可能使得多種類的不一樣對象的hashcode值不一樣,這樣才能夠提升HashSet在檢索元素時的效率,不然可能檢索效率還不如List。注意:兩個對象值相同(x.equals(y) == true),但卻可有不一樣的hash code。