第一篇:對java集合類的一些總結(jié)
13、java中的集合類
答:所有的集合類都實(shí)現(xiàn)了iterator接口,用于遍歷集合中的元素,iterator接口中的方法有hashNext(),next(),remove()三種方法,不同的集合類提供了不同的實(shí)現(xiàn)(無序集合實(shí)現(xiàn)這個(gè)接口,只能向后遍歷)。如果要實(shí)現(xiàn)向前遍歷,也就是說集合中的元素是有序的,實(shí)現(xiàn)的是linkedIterator接口,這是iterator的子接口,實(shí)現(xiàn)了這個(gè)接口的類能實(shí)現(xiàn)雙向(前后)遍歷。
Hashset:hashset繼承了抽象類AbstractSet,而AbstractSet類又實(shí)現(xiàn)了set接口,并且AbstactSet又繼承了AbstractCollection,AbstractCollection實(shí)現(xiàn)了Collection接口,因此hashset實(shí)際上實(shí)現(xiàn)了collection接口,又實(shí)現(xiàn)了set接口,因?yàn)樗械募辖涌诙紝?shí)現(xiàn)了iterator接口,因此hashset可以上轉(zhuǎn)型為set,collection,以及iterator,并且調(diào)用響應(yīng)的方法。特點(diǎn):hashset不能存放重復(fù)的元素,并且采用散列的存儲(chǔ)方法,因此元素的插入與輸出并不是一致的。附:散列是使用了數(shù)組和鏈表來進(jìn)行存儲(chǔ)的一種結(jié)構(gòu),數(shù)組是連續(xù)的,每個(gè)數(shù)組的元素都是一條鏈表。
ArrayList:ArrayList繼承了AbstractList并且實(shí)現(xiàn)了List接口。其中AbstractList繼承了AbstractCollection并且實(shí)現(xiàn)了List接口,AbstractCollection實(shí)現(xiàn)了Collection接口,因此AbstractList可以說是間接或者是直接實(shí)現(xiàn)了List,Collection,iterator接口。ArrayList使用的數(shù)據(jù)結(jié)構(gòu)是數(shù)組。方便對元素的檢索,但是增刪需要移動(dòng)數(shù)組元素,因此不適合增刪,增刪使用鏈?zhǔn)酱鎯?chǔ)的線性表(如:LinkedList)會(huì)比較方便,詳細(xì)見LinkedList。
LinkedList:linkedList繼承了AbstractSequentialList并且實(shí)現(xiàn)了List接口,AbstractSequentialList繼承了AbstractList,Abstractlist繼承了AbstractCollection接口,因此LinkedList也是有序集合。LinkedList在java中的實(shí)現(xiàn)是雙向鏈表,因此LinkedList對空間的利用率比較高,但是對元素的檢索較慢,但是增刪較快,只需要簡單調(diào)整鏈的指向即可。
Vector:Vector的結(jié)構(gòu)和ArrayList幾乎相同,不同的地方就是在公有方法層次上,Vector加了關(guān)鍵字synchronized,因此理論上來說,Vector每個(gè)方法都是現(xiàn)成安全的。但是個(gè)人認(rèn)為(包括查資料了解到)這并不能完全保證并發(fā)訪問下的線程安全。在并發(fā)訪問情況下,任何時(shí)候都只能有一個(gè)線程去訪問其中的共有方法,在方法級別是線程安全的。但是現(xiàn)在有兩個(gè)線程A、B,線程A向Vector添加一個(gè)對象,此時(shí)線程B查詢Vector的長度是1,但是線程B并沒有進(jìn)行任何操作(插入操作),這樣仍然會(huì)造成并發(fā)問題,但是在線程A、B都進(jìn)行插入操作的時(shí)候,jvm會(huì)根據(jù)自動(dòng)進(jìn)行線程調(diào)度從而確保在任何時(shí)刻只有一個(gè)線程操作Vector的插入操作。因此在Vector之后,新版的jdk里面有了arraylist(非線程安全),其實(shí)我認(rèn)為就是把并發(fā)控制的問題交給程序員處理。
Stack:Stack是棧結(jié)構(gòu),后進(jìn)先出。Stack繼承Vector,并且新增了一些方法,例如出棧,入棧操作。Stack內(nèi)部的方法也是加了synchronized關(guān)鍵字的,因此,也是“線程安全”的。
HashMap:HashMap繼承了AbstractMap并且實(shí)現(xiàn)了Map接口,而AbstractMap也實(shí)現(xiàn)了Map接口,總的來說hashMap實(shí)現(xiàn)了Map接口以及abstractMap的一些方法。hashMap是通過鍵值對來存儲(chǔ)以及檢索數(shù)據(jù)的。HashMap是通過一個(gè)數(shù)組以及鏈表組合來存儲(chǔ)數(shù)據(jù)的。java中的hashMap的實(shí)現(xiàn)是一個(gè)長度為16的數(shù)組,并且每個(gè)數(shù)組存儲(chǔ)都是一個(gè)單鏈表,存儲(chǔ)一個(gè)數(shù)據(jù)的時(shí)候,根據(jù)key的hash值去判斷到底應(yīng)該存在下標(biāo)為多少的數(shù)組中,找到對應(yīng)的數(shù)組位置后,并且一直對這個(gè)位置的鏈向后索引,查到鏈的最后面。hashMap綜合了線性表以及鏈表的優(yōu)點(diǎn),使檢索以及增刪都變得方便。附:非線程安全,并且hashMap可以存儲(chǔ)null值
HashTable:HashTable也是一個(gè)散列表(和hashMap一樣),存儲(chǔ)的是鍵值對,HashTable繼承于Dictionary,實(shí)現(xiàn)了Map接口,和hashMap最大的區(qū)別是:hashTable的讀寫方法是線程安全的,加了synchronized關(guān)鍵字,而且hashtable不能存儲(chǔ)null。
ConcurrenHashMap:其實(shí)ConcurrenHashMap,HashMap和HashTable三者的數(shù)據(jù)結(jié)構(gòu)是一致的,唯一不同的是鎖機(jī)制。ConcurrtnHashMap的鎖機(jī)制控制得更加細(xì)粒度,不是像hashMap那樣在方法層面上加鎖,而是在訪問的數(shù)組特定索引位置加鎖,例如插入操作,加入兩個(gè)線程都需要對下邊為5的線程執(zhí)行插入操作,那么只能在一個(gè)線程插入操作完成之后釋放鎖,另一個(gè)線程才能執(zhí)行插入操作,但是兩個(gè)操作分別在不同的下標(biāo)索引進(jìn)行插入,則兩個(gè)線程可以并發(fā)進(jìn)行。(這和好老師項(xiàng)目中投票功能中數(shù)據(jù)庫數(shù)據(jù)訪問帶來的并發(fā)問題基本一樣,本來通過對整個(gè)投票功能加鎖,但是考慮到對同一個(gè)老師投票才加鎖,對不同的老師投票不需要加鎖,因此對數(shù)據(jù)庫中的特定老師的特定字段加鎖,從而提高了系統(tǒng)性能)而hashtable在方法層面上加鎖,也就是說無論多個(gè)線程往哪一條鏈插入操作,都會(huì)鎖表,因此高并發(fā)的情況下會(huì)造成阻塞,嚴(yán)重影響系統(tǒng)性能,而ConcurrentHashMap則很好得權(quán)衡了這個(gè)問題,保證了數(shù)據(jù)的正確性,又減少系統(tǒng)性能消耗。
第二篇:【java總結(jié)】集合框架
【java總結(jié)】集合框架
Collection是集合框架層次結(jié)構(gòu)中的根接口。Collection 表示一組對象,這些對象也稱為 collection 的元素。一些 collection 允許有重復(fù)的元素,而另一些則不允許。一些 collection 是有序的,而另一些則是無序的。Collection接口下有最常用的接口為List跟Set。需要注意的是,Map并沒有實(shí)現(xiàn)Collection接口。
List接口實(shí)現(xiàn)類ArrayList 優(yōu)點(diǎn):類似數(shù)組的形式進(jìn)行存儲(chǔ),因此它的隨機(jī)訪問速度極快。缺點(diǎn):不適合于在線性表中間需要頻繁進(jìn)行插入和刪除操作。因?yàn)槊看尾迦牒蛣h除都需要移動(dòng)數(shù)組中的元素,它是用數(shù)組存儲(chǔ)元素的,這個(gè)數(shù)組可以動(dòng)態(tài)創(chuàng)建,如果元素個(gè)數(shù)超過了數(shù)組的容量,那么就創(chuàng)建一個(gè)更大的新數(shù)組,并將當(dāng)前數(shù)組中的所有元素都復(fù)制到新數(shù)組中。[html] view plain copy public class ArrayListTest {
public static void main(String[] args){
List
arrayList.add(“Welcome”);
arrayList.add(“to”);
arrayList.add(“java”);
//把ArrayList變?yōu)閿?shù)組相關(guān)的內(nèi)容進(jìn)行遍歷
String[] strArray=new String[arrayList.size()];
arrayList.toArray(strArray);
for(int i=0;i //使用迭代器進(jìn)行ArrayList遍歷 Iterator while(iter.hasNext()){ System.out.println(iter.next()); } } } List接口實(shí)現(xiàn)類LinkedList 優(yōu)點(diǎn):適合于在鏈表中間需要頻繁進(jìn)行插入和刪除操作。 缺點(diǎn): 隨機(jī)訪問速度較慢。查找一個(gè)元素需要從頭開始一個(gè)一個(gè)的找。此類實(shí)現(xiàn) Deque 接口,為 add、poll 提供先進(jìn)先出隊(duì)列操作,以及其他堆棧和雙端隊(duì)列操作LinkedList是在一個(gè)鏈表中存儲(chǔ)元素。[html] view plain copy public class LinkedListTest { public static void main(String[] args){ List //使用ForEach遍歷linkedList String[] strArray2=new String[linkedList.size()]; linkedList.toArray(strArray2); for(int i=0;i //foreach遍歷LinkedList for(String str:linkedList){ System.out.println(str); } //使用迭代器進(jìn)行ArrayList遍歷 Iterator while(iter.hasNext()){ System.out.println(iter.next()); } } } List接口實(shí)現(xiàn)類Vector: Vector使用了關(guān)鍵字synchronized將訪問和修改向量的方法都變成同步的了,所以對于不需要同步的應(yīng)用程序來說,類ArrayList比類Vector更高效。相同點(diǎn): ①都繼承于AbstractList,并且實(shí)現(xiàn)List接口 ②都實(shí)現(xiàn)了RandomAccess和Cloneable接口 ③都是通過數(shù)組實(shí)現(xiàn)的,本質(zhì)上都是動(dòng)態(tài)數(shù)組,默認(rèn)數(shù)組容量是10 ④都支持Iterator和listIterator遍歷 不同點(diǎn): ①ArrayList是非線程安全,而Vector是線程安全的 ②容量增加方式不同,Vector默認(rèn)增長為原來一倍,而ArrayList卻是原來的一半+1 ③Vector支持通過Enumeration去遍歷,而List不支持 [html] view plain copy public class VectorTest { public static void main(String[] args){ Vector for(int i = 0;i < 10;i++){ vector.add(i); } //直接打印 System.out.println(vector.toString()); //size() System.out.println(vector.size()); //contains System.out.println(vector.contains(2)); //總結(jié):對比Vector的遍歷方式,使用索引的隨機(jī)訪問方式最快,使用迭代器最慢 //iterator遍歷 Iterator while(iterator.hasNext()){ System.out.print(iterator.next()+ “ ”); } //Enumeration遍歷 Enumeration enu = vector.elements(); while(enu.hasMoreElements()){ System.out.println((Integer)enu.nextElement()); } //toArray Object[] objArr = vector.toArray(); System.out.println(“nobjArr:” + Arrays.asList(objArr)); Integer[] intArr = vector.toArray(new Integer[vector.size()]); System.out.println(“intArr:” + Arrays.asList(intArr)); //add vector.add(5); //remove vector.remove(5); System.out.println(vector); //containsAll System.out.println(vector.containsAll(Arrays.asList(5,6))); //addAll vector.addAll(Arrays.asList(555,666)); System.out.println(vector); //removeAll vector.removeAll(Arrays.asList(555,666)); System.out.println(vector); //addAll方法 vector.addAll(5, Arrays.asList(666,666, 6)); System.out.println(vector); //get方法 System.out.println(vector.get(5)); //set方法 vector.set(5, 55); System.out.println(vector.get(5)); //add方法 vector.add(0, 555); System.out.println(vector); //remove方法 vector.remove(0); System.out.println(vector); //indexof方法 System.out.println(vector.indexOf(6)); //lastIndexOf方法 System.out.println(vector.lastIndexOf(6)); //listIterator方法 ListIterator System.out.println(listIterator.hasPrevious()); //listIterator(index)方法 ListIterator System.out.println(iListIterator.previous()); //subList方法 System.out.println(vector.subList(5, 7)); //clear vector.clear(); System.out.println(vector); } } List接口實(shí)現(xiàn)類Stack 棧類,是Java2之前引入的,繼承自類Vector。同樣是線程同步的 [html] view plain copy public class StackTest { public static void main(String[] args){ Stack for(int i = 0;i < 10;i++){ stack.add(i); } System.out.println(stack); System.out.println(stack.peek()); stack.push(555); System.out.println(stack); System.out.println(stack.pop()); System.out.println(stack); System.out.println(stack.empty()); System.out.println(stack.search(6)); System.out.println(“stack遍歷:”); while(!stack.empty()){ System.out.print(stack.pop()+ “ ”); } } } List接口總結(jié):實(shí)際使用中我們需要根據(jù)特定的需求選用合適的類,如果 除了在末尾外不能在其他位置插入或者刪除元素,那么ArrayList效率更高,如果需要經(jīng)常插入或者刪除元素,就選擇LinkedList。 Set接口實(shí)現(xiàn)類HashSet: HashSet是Set接口最常見的實(shí)現(xiàn)類,其底層是基于hash算法進(jìn)行存儲(chǔ)相關(guān)元素的。HashSet中存儲(chǔ)元素的位置是固定的(由hashCode決定),并且是無序的。Set集合中的去重和hashCode與equals方法相關(guān)。[html] view plain copy public class Num implements Comparable{ private int num; public Num(int num){ this.num=num; } @Override public int compareTo(Object o){ // TODO Auto-generated method stub Num x=(Num)o; if(num>x.num)return 1; else if(num==x.num)return 0; else return-1; } public String toString(){ return “num=”+num; } } [html] view plain copy public class HashSetTest { public static void main(String[] args){ Set hashSet.add(“hello”); hashSet.add(“world”); hashSet.add(“world”); //使用數(shù)組的方法遍歷HashSet集合String[] strArray=new String[hashSet.size()]; strArray=hashSet.toArray(strArray); for(String str:strArray){ System.out.println(str); } //使用HashSet集合直接遍歷 for(String str:hashSet){ System.out.println(str); } //用迭代器遍歷HashSet集合Iterator while(iterator.hasNext()){ System.out.println(iterator.next()); } //無重寫hashCode跟equals方法的類,不會(huì)自動(dòng)根據(jù)類中的值進(jìn)行去重 Set set2.add(new Num(1)); set2.add(new Num(3)); set2.add(new Num(2)); set2.add(new Num(3)); set2.add(new Num(3)); set2.add(new Num(6)); System.out.println(set2.size()); Iterator while(iterator2.hasNext()){ System.out.println(iterator2.next()); } } } Set接口實(shí)現(xiàn)類LinkedHashSet: LinkedHashSet繼承HashSet,是用一個(gè)鏈表實(shí)現(xiàn)來擴(kuò)展HashSet類,它支持對規(guī)則集內(nèi)的元素排序。HashSet中的元素是沒有被排序的,而LinkedHashSet中的元素可以按照它們插入規(guī)則集的順序提取。[html] view plain copy public class LinkedHashSetTest { public static void main(String[] args){ Set linkedHashSet.add(“hello”); linkedHashSet.add(“world”); linkedHashSet.add(“world”); //使用數(shù)組的方法遍歷HashSet集合String[] strArray=new String[linkedHashSet.size()]; strArray=linkedHashSet.toArray(strArray); for(String str:strArray){ System.out.println(str); } //使用HashSet集合直接遍歷 for(String str:linkedHashSet){ System.out.println(str); } //用迭代器遍歷HashSet集合Iterator while(itera004km.cntor.hasNext()){ System.out.println(iterator.next()); } } } Set接口實(shí)現(xiàn)類TreeSet: TreeSet實(shí)現(xiàn)了Set接口,它與HashSet的區(qū)別主要在于TreeSet中的元素會(huì)按照相關(guān)的值進(jìn)行排序。HashSet是通過HashMap實(shí)現(xiàn)的,TreeSet是通過TreeMap實(shí)現(xiàn)的,只不過Set用的只是Map的key。由于TreeMap需要排序,所以需要一個(gè)Comparator為鍵值進(jìn)行大小比較.當(dāng)然也是用Comparator定位的.如果創(chuàng)建時(shí)沒有確定,那么就會(huì)使用key.compareTo()方法,這就要求key必須實(shí)現(xiàn)Comparable接口.TreeMap是使用Tree數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,所以使用compare接口就可以完成定位了.注意:TreeSet是根據(jù)對象的CompareTo方法來去重的,如果CompaerTo返回0說明兩個(gè)對象相等,不能同時(shí)存在于TreeSet中。 [html] view plain copy public class TreeSetTest { public static void main(String[] args){ Set treeSet.add(“d”); treeSet.add(“c”); treeSet.add(“b”); treeSet.add(“a”); //String實(shí)體類中實(shí)現(xiàn)Comparable接口,所以在初始化TreeSet的時(shí)候, //無需傳入比較器 Iterator while(iterator.hasNext()){ System.out.println(iterator.next()); } Set treeSet2.add(new Num(1)); treeSet2.add(new Num(3)); treeSet2.add(new Num(2)); treeSet2.add(new Num(3)); treeSet2.add(new Num(3)); treeSet2.add(new Num(6)); System.out.println(treeSet2.size()); Iterator while(iterator2.hasNext()) { System.out.println(iterator2.next()); } TreeSet set.add(1111); set.add(2222); set.add(3333); set.add(4444); set.add(5555); System.out.println(set.first());// 輸出第一個(gè)元素 System.out.println(set.lower(3333));//小于3333的最大元素 System.out.println(set.higher(2222));//大于2222的最大元素 System.out.println(set.floor(3333));//不大于3333的最大元素 System.out.println(set.ceiling(3333));//不小于3333的最大元素 System.out.println(set.pollFirst());//刪除第一個(gè)元素 System.out.println(set.pollLast());//刪除最后一個(gè)元素 System.out.println(set); } } Set接口區(qū)別于List接口在于: 所有Set中的元素實(shí)現(xiàn)了不重復(fù),有點(diǎn)像數(shù)學(xué)中集合的概念,無序,不允許有重復(fù)的元素,最多允許有一個(gè)null元素對象 Map接口: Map接口儲(chǔ)存一組成對的鍵-值對象,提供key(鍵)到value(值)的映射,Map中的key不要求有序,不允許重復(fù)。value同樣不要求有序,但可以重復(fù)。 Map實(shí)現(xiàn)類HashMap 最常見的Map實(shí)現(xiàn)類,他的儲(chǔ)存方式是哈希表,優(yōu)點(diǎn)是查詢指定元素效率高。HashMap采用數(shù)組+鏈表實(shí)現(xiàn),即使用鏈表處理沖突,同一hash值的鏈表都存儲(chǔ)在一個(gè)鏈表里。但是當(dāng)鏈表中的元素較多,即hash值相等的元素較多時(shí),通過key值依次查找的效率較低。而JDK1.8中,HashMap采用數(shù)組+鏈表+紅黑樹實(shí)現(xiàn),當(dāng)鏈表長度超過閾值(8)時(shí),將鏈表轉(zhuǎn)換為紅黑樹,這樣大大減少了查找時(shí)間。 無論什么情況HashMap中哈希表的容量總是2的n次方的一個(gè)數(shù)。并且有這樣一個(gè)公式:當(dāng)length=2^n時(shí),hashcode &(length-1)== hashcode % length HashMap與Hashtable的區(qū)別: Hashtable實(shí)現(xiàn)Map接口,繼承自古老的Dictionary類,實(shí)現(xiàn)一個(gè)key-value的鍵值映射表。任何非空的(key-value)均可以放入其中。區(qū)別主要有三點(diǎn): 1.Hashtable是基于陳舊的Dictionary實(shí)現(xiàn)的,而HashMap是基于Java1.2引進(jìn)的Map接口實(shí)現(xiàn)的; 2.Hashtable是線程安全的,而HashMap是非線程安全的,我們可以使用外部同步的方法解決這個(gè)問題。 3.HashMap可以允許你在列表中放一個(gè)key值為null的元素,并且可以有任意多value為null,而Hashtable不允許鍵或者值為null。 [html] view plain copy public class HashMapTest { public static void main(String[] args){ Map hashMap.put(“a”,1); hashMap.put(“b”,2); hashMap.put(“JAVA”,3); System.out.println(hashMap.get(“JAVA”)); //第一種遍歷方法:普遍使用,二次取值 for(String key : hashMap.keySet()){ System.out.println(“key= ”+ key + “ and value= ” + hashMap.get(key)); } //第二種:通過Map.entrySet使用iterator遍歷key和value Iterator while(iter.hasNext()){ System.out.println(iter.next()); } //第三種:通過Map.entrySet遍歷key和value.推薦,尤其是容量大時(shí) for(Map.Entry System.out.println(“key= ” + entry.getKey()+ “ and value= ” + entry.getValue()); } //第四種:通過Map.values()遍歷所有的value,但不能遍歷key for(Integer v : hashMap.values()){ System.out.println(“value= ” + v); } } } Map實(shí)現(xiàn)類LinkedHashMap LinkedHashMap繼承自HashMap,它主要是用鏈表實(shí)現(xiàn)來擴(kuò)展HashMap類,HshMap中條目是沒有順序的,但是在LinkedHashMap中元素既可以按照它們插入圖的順序排序,也可以按它們最后一次被訪問 的順序排序。LinkedHashMap繼承自HashMap并且實(shí)現(xiàn)了Map接口。和HashMap一樣,LinkedHashMap 允許key和value均為null。于該數(shù)據(jù)結(jié)構(gòu)和HashMap一樣使用到hash算法,因此它不能保證映射的順序,尤其是不能保證順序持久不變(再哈希)。 [html] view plain copy public class LinkedHashMapTest { public static void main(String[] args){ Map linkedHashMap.put(“a”, 1); linkedHashMap.put(“java”,2); linkedHashMap.put(“C”, 3); System.out.println(linkedHashMap.get(“a”)); Set Iterator while(iter.has004km.cnn(String[] args){ Map treeMap.put(“b”,2); treeMap.put(“a”,1); treeMap.put(“e”,5); treeMap.put(“d”,4); treeMap.put(“c”,3); Set Iterator while(iter.hasNext()){ System.out.println(iter.next()); } Set for(String x:keySet){ System.out.println(x+“=”+treeMap.get(x)); } Map treeMap2.put(new Num(2),“a”); treeMap2.put(new Num(1),“b”); treeMap2.put(new Num(5),“c”); treeMap2.put(new Num(4),“d”); treeMap2.put(new Num(3),“c”); Set for(Num x:ke004km.cnySet2){ System.out.println(x+“=”+treeMap2.get(x)); } //根據(jù)value排序 Map map.put(“d”, 2); map.put(“c”, 1); map.put(“b”, 4); map.put(“a”, 3); List new ArrayList //排序前 for(int i = 0;i < infoIds.size();i++){ String id = infoIds.get(i).toString(); System.out.println(id); } //排序 Collections.sort(infoIds, new Comparator public int compare(Map.Entry return(o2.getValue()-o1.getValue()); //return(o1.getKey()).toString().compareTo(o2.getKey()); } }); //排序后 for(int i = 0;i < infoIds.size();i++){ String id = infoIds.get(i).toString(); System.out.println(id); } } } Map接口總結(jié):在實(shí)際使用中,如果更新圖時(shí)不需要保持圖中元素的順序,就使用HashMap,如果需要保持圖中元素的插入順序或者訪問順序,就使用LinkedHashMap,如果需要使圖按照鍵值排序,就使用TreeMap。 java集合總結(jié) (一)一、數(shù)組、集合數(shù)組、集合:都是一種容器,用一個(gè)對象管理多個(gè)對象; 數(shù)組:不能自動(dòng)增長;只能存放同類型的元素 集合:能自動(dòng)擴(kuò)容;部分集合允許存放不同類型的元素; 二、學(xué)習(xí)這些集合類要掌握哪些東西: 1)怎樣得到(選擇)集合對象; 2)怎樣添加元素 3)怎樣刪除元素 4)怎樣循環(huán)遍歷沒一個(gè)元素 三、list、set、map collection:父接口; Set:接口---一個(gè)實(shí)現(xiàn)類:HashSet List:接口---三個(gè)實(shí)現(xiàn)類:LinkedList,Vector,ArrayList SortedSet:接口---實(shí)現(xiàn)類:TreeSet1、List: List:有序列表,允許存放重復(fù)的元素; 實(shí)現(xiàn)類: ArrayList:數(shù)組實(shí)現(xiàn),查詢快,增刪慢,線程不安全,輕量級;下標(biāo)也是從0開始; LinkedList:鏈表實(shí)現(xiàn),增刪快,查詢慢 Vector:數(shù)組實(shí)現(xiàn),線程安全,重量級 2.Set: 無序集合,不允許存放重復(fù)的元素; 實(shí)現(xiàn)類HashSet:equals返回true,hashCode返回相同的整數(shù);哈希表; 子接口SortedSet:對Set排序?qū)崿F(xiàn)類:TreeSet:二叉樹實(shí)現(xiàn)的; 看API: Iterator:接口,迭代器; java.util; hasNext(); next(); remove(); Iterable:可迭代的,訪問的; ng;實(shí)現(xiàn)了可迭代的接口就可以用迭代的方式訪問; 只需實(shí)現(xiàn)iterator();方法即可;Iteratoriterator(); 三種循環(huán)的訪問方式: 只有實(shí)現(xiàn)了Iterable接口的才能用第三種;能用第二種的也一定能用第三種; ArrayList:自動(dòng)擴(kuò)容,是數(shù)組照搬過來的; 3.Map HashMap:鍵值對,key不能重復(fù),但是value可以重復(fù);key的實(shí)現(xiàn)就是HashSet;value對應(yīng)著放; HashSet的后臺(tái)有一個(gè)HashMap;初始化后臺(tái)容量;只不過生成一個(gè)HashSet的話,系統(tǒng)只提供key的訪問; 如果有兩個(gè)Key重復(fù),那么會(huì)覆蓋之前的; Hashtable:線程安全的Properties:java.util.Properties;key和value都是String類型,用來讀配置文件; HashMap與Hashtable區(qū)別: HashMap線程不安全的,允許null作為key或value; Hashtable線程安全的,不允許null作為key或value; TreeMap:對key排好序的Map;key就是TreeSet,value對應(yīng)每個(gè)key; key要實(shí)現(xiàn)Comparable接口或TreeMap有自己的構(gòu)造器; HashSet:remove(Objecto)的原則看這個(gè)對象O的Hashcode和equals是否相等,并不是看是不是一個(gè)對象; 定義一個(gè)Map;key是課程名稱,value是Integer表示選課人數(shù); map.put(cou,map.get(cou)+newInteger(1)); 四、Hashtable、Properties 1,Hashtable:實(shí)現(xiàn)了Map接口,此類實(shí)現(xiàn)一個(gè)哈希表,作用和HashMap相同。任何非null對象都可以用作鍵或值。為了成功地在哈希表中存儲(chǔ)和獲取對象,用作鍵的對象必須實(shí)現(xiàn)hashCode方法和equals法。 2,Properties:繼承自Hashtable,比Hashtable更嚴(yán)格屬性列表中每個(gè)鍵及其對應(yīng)值都是一個(gè)字符串。 常用方法StringgetProperty(String?key)和setProperty(Stringkey,Stringvalue); 用法:我在C盤下建了一個(gè)名為yy.dat的文件,文件的內(nèi)容為: name=hehe password=1234 5執(zhí)行以下程序,輸出hehe,可見用Properties可以很方便的解析配置文件 Propertiesp=newProperties(); p.load(newFileInputStream(“C:yy.dat”)); System.out.println(p.getProperty(“name”)) 五、兩個(gè)工具類Arrays和Collections 1.Arrays、此類包含用來操作數(shù)組(比如排序和搜索)的各種方法。此類還包含一個(gè)允許將數(shù)組作為列表來查看的靜態(tài)工廠 2.Collections、主要提供了在collection上進(jìn)行操作的靜態(tài)方法 六、遺留的幾個(gè)類 1.Hashtable,作用和HashMap相同,不過它是線程安全的,如果不需要線程安全,應(yīng)該使用HashMap 2.Enumeration,遺留集合使用枚舉接口來遍歷元素,它有兩個(gè)方法,hasMoreElements和nextElement,用法類似Iterator。 3.Stack,繼承自Vector,實(shí)現(xiàn)了棧的功能,提供了push()方法押棧和pop()方法出棧。 4.BitSet,位集。如果需要高效率的存儲(chǔ)一個(gè)位序列,例如一個(gè)標(biāo)志序列,請使用位集。它可以對各個(gè)位進(jìn)行 讀取get(i) 設(shè)置set(i) 清楚clear(i) 七、常見筆試題目匯總 1.Collection和Collections的區(qū)別。 Collection是集合類的上級接口,繼承與他的接口主要有Set和List.Collections是針對集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對各種集合的搜索、排序、線程安全化等操作。 2.List,Set,Map是否繼承自Collection接口? List,Set是,Map不是 3.兩個(gè)對象值相同(x.equals(y)==true),但卻可有不同的hashcode,這句話對不對? 不對,有相同的hashcode。 4.你所知道的集合類都有哪些?主要方法? 最常用的集合類是List和Map。List的具體實(shí)現(xiàn)包括ArrayList和Vector,它們是可變大小的列表,比較適合構(gòu)建、存儲(chǔ)和操作任何類型對象的元素列表。List適用于按數(shù)值索引訪問元素的情形。 Map提供了一個(gè)更通用的元素存儲(chǔ)方法。Map集合類用于存儲(chǔ)元素對(稱作“鍵”和“值”),其中每個(gè)鍵映射到一個(gè)值。 5.排序都有哪幾種方法?請列舉。用JAVA實(shí)現(xiàn)一個(gè)快速排序。 排序的方法有:插入排序(直接插入排序、希爾排序),交換排序(冒泡排序、快速排序),選擇排序(直接選擇排序、堆排序),歸并排序,分配排序(箱排序、基數(shù)排序) 快速排序的偽代碼。 //使用快速排序方法對a[0:n-1]排序 從a[0:n-1]中選擇一個(gè)元素作為middle,該元素為支點(diǎn) 把余下的元素分割為兩段left和right,使得left中的元素都小于等于支點(diǎn),而right中的元素都大于等于支點(diǎn) 遞歸地使用快速排序方法對left進(jìn)行排序 遞歸地使用快速排序方法對right進(jìn)行排序 所得結(jié)果為left+middle+right 6.HashMap和Hashtable的區(qū)別 都屬于Map接口的類,實(shí)現(xiàn)了將惟一鍵映射到特定的值上。 HashMap類沒有分類或者排序。它允許一個(gè)null鍵和多個(gè)null值。 Hashtable類似于HashMap,但是不允許null鍵和null值。它也比HashMap慢,因?yàn)樗峭降摹?/p> 7.Set里的元素是不能重復(fù)的,那么用什么方法來區(qū)分重復(fù)與否呢?是用==還是equals()它們有何區(qū)別? Set里的元素是不能重復(fù)的,那么用iterator()方法來區(qū)分重復(fù)與否。 equals()是判讀兩個(gè)Set是否相等。 equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當(dāng)兩個(gè)分離的對象的內(nèi)容和類型相配的話,返回真值。 java集合總結(jié) (二)java集合類主要負(fù)責(zé)保存、盛裝其他數(shù)據(jù),因此集合類也稱容器類。java集合類分為:set、list、map、queue四大體系。其中set代表無序、不可重復(fù)的集合;list代表有序、可重復(fù)的集合。map代表具有映射關(guān)系的集合;queue代表隊(duì)列集合。 java集合類主要由兩個(gè)接口派生:Collection和Map,是集合框架的根接口。下面是其接口、子接口和實(shí)現(xiàn)類的繼承樹。 下面就一一介紹四大接口及其實(shí)現(xiàn)類。 Set接口。set集合不允許包含相同的元素。set判斷兩個(gè)對象是否相同是根據(jù)equals方法。如果兩個(gè)對象用equals方法返回的是true,set不會(huì)接受這兩個(gè)對象。 HashSet是set接口的典型實(shí)現(xiàn),HashSet按hash算法來存儲(chǔ)集合中的元素。因此具有很好的存儲(chǔ)和查找性能。HashSet判斷兩個(gè)元素的標(biāo)準(zhǔn)是兩個(gè)元素的equals方法比較相等,同時(shí)兩個(gè)對象的hasCode()方法返回值也相等。HashSet可以保存null元素。 List集合代表一個(gè)有序集合。集合中的每個(gè)元素都有其對應(yīng)的順序索引。Arraylist和vector是list接口的兩個(gè)典型實(shí)現(xiàn)。他們之間的顯著區(qū)別就是:vector是線性安全的,而arraylist不是。它們兩個(gè)都是基于數(shù)組實(shí)現(xiàn)的list類。List還有一個(gè)基于鏈表實(shí)現(xiàn)的LinkedList類。當(dāng)插入、刪除元素的速度非??臁_@個(gè)類比較特殊,功能也特別多,即實(shí)現(xiàn)了List接口,也實(shí)現(xiàn)了Dueue接口(雙向隊(duì)列)??梢援?dāng)成雙向隊(duì)列使用,也可以當(dāng)成棧使用。 Queue用于模擬隊(duì)列的數(shù)據(jù)結(jié)構(gòu)。LinkedList和ArrayDueue是其兩個(gè)比較常用的實(shí)現(xiàn)類。 Map用于保存具有映射關(guān)系的數(shù)據(jù)。Map接口有如下幾個(gè)常用的實(shí)現(xiàn)類:HashMap、HashTable、TreeMap。TreeMap是基于紅黑樹對TreeMap中所有key進(jìn)行排序。HashMap和HashTable主要區(qū)別有兩點(diǎn): 1、Hashtable是線性安全的,因此性能差些。 2、HashMap可以使用null作為key或者value。 集合類還提供了一個(gè)工具類Collections。主要用于查找、替換、同步控制、設(shè)置不可變集合。 上面是對java集合類的一般概述,下面就set、list、map三者之間的關(guān)系進(jìn)行剖析。 Set與Map的關(guān)系。Map集合中所有key集中起來,就組成了一個(gè)set集合。所以Map集合提供Set Map與List的關(guān)系。把Map的key-value分開來看,從另一個(gè)角度看,就可以把Map與List統(tǒng)一起來。 Map集合是一個(gè)關(guān)聯(lián)數(shù)組,key可以組成Set集合,Map中的value可以重復(fù),所以這些value可以組成一個(gè)List集合。但是需要注意的是,實(shí)質(zhì)Map的values方法并未返回一個(gè)List集合。而是返回一個(gè)不存儲(chǔ)元素的Collection集合,換一種角度來看對List集合,它也包含了兩組值,其中一組就是虛擬的int類型的索引,另一組就是list集合元素,從這個(gè)意思上看,List就相當(dāng)于所有key都是int型的Map。 下面講解幾個(gè)相似類之間的差異。 ArrayList和LinkedList。ArrayList是一種順序存儲(chǔ)的線性表,其底層是采用數(shù)組實(shí)現(xiàn)的,而LinkedList是鏈?zhǔn)酱鎯?chǔ)的線性表。其本質(zhì)就是一個(gè)雙向鏈表。對于隨機(jī)存儲(chǔ)比較頻繁的元素操作應(yīng)選用ArrayList,對于經(jīng)常需要增加、刪除元素應(yīng)該選用LinkedList。但總的來說ArrayList的總體性能還是優(yōu)于LinkedList。 HashSet與HashMap的性能選項(xiàng)。主要有兩個(gè)方面:容量和負(fù)載因子(尺寸/容量)。較低負(fù)載因子會(huì)增加查詢數(shù)據(jù)的性能,但是會(huì)降低hash表所占的內(nèi)存開銷。較高負(fù)載因子則反之,一般對數(shù)據(jù)的查詢比較頻繁,所以一般情況下初始容量應(yīng)該大一點(diǎn),但也不能太大,否則浪費(fèi)內(nèi)存空間。 黑馬程序員:Java集合簡單總結(jié) 在Java語言中,學(xué)好集合是非常重要的,下面簡單的對集合進(jìn)行總結(jié),以便大家學(xué)習(xí),有 問題再相互交流。 集合框架圖 在集合框架圖中可以看出,Collection接口中主要有兩個(gè)子接口,分別是List和Set。List集合的特點(diǎn)是元素有序、包含重復(fù)元素,Set集合的特點(diǎn)是元素?zé)o序、不包含重復(fù)元素。Map集合中存儲(chǔ)的是鍵值映射關(guān)系,元素都是成對出現(xiàn)的。Map接口的主要子接口有HashMap和TreeMap。 總結(jié)ist有順序有重復(fù)沒有排序,set無重復(fù)有排序,map的key也和set一樣。 List接口 List : 特點(diǎn)是元素有序、可以包含重復(fù)元素。它有兩個(gè)實(shí)現(xiàn)類分別是:ArrayList和LinkedList。 ArrayList : 內(nèi)部維護(hù)一個(gè)數(shù)組結(jié)構(gòu),允許對元素進(jìn)行快速隨機(jī)訪問,但是向List中間插入與移除元素的速度很慢。 LinkedList : 內(nèi)部維護(hù)了一個(gè)雙向鏈表結(jié)構(gòu),即通過節(jié)點(diǎn)之間彼此連接來實(shí)現(xiàn)的,每一個(gè)節(jié)點(diǎn)都包含前一個(gè)節(jié)點(diǎn)和后一個(gè)節(jié)點(diǎn)的引用。當(dāng)一個(gè)新節(jié)點(diǎn)插入時(shí),只需要修改其中保持先后關(guān)系的節(jié)點(diǎn)引用即可,這樣的存儲(chǔ)結(jié)構(gòu)保證了LinkedList集合在增刪元素時(shí)效率非常高。 Set接口 Set具有與Collection完全一樣的接口,因此沒有任何額外的功能,不像前面的List。實(shí)際上Set就是Collection只是行為不同,也就是說Set集合并沒有對Collection接口進(jìn)行擴(kuò)充,只是比collection接口要求更加嚴(yán)了。 Set : 存入Set的每個(gè)元素都必須是唯一的,因?yàn)镾et不保存重復(fù)元素。加入Set的元素必須定義equals()方法以確保對象的唯一性。 HashSet : 為快速查找設(shè)計(jì)的Set。存入HashSet的對象必須定義hashCode()。 TreeSet : 保存有序的Set, 底層為樹結(jié)構(gòu)。使用它可以從Set中提取有序的序列。 LinkedHashSet : 具有HashSet的查詢速度,且內(nèi)部使用鏈表維護(hù)元素的順序。于是在使用迭代器遍歷Set時(shí),結(jié)果會(huì)按元素插入的次序顯示。 Map接口 Map用于保存具有映射關(guān)系的數(shù)據(jù),因此Map集合里存儲(chǔ)兩組值,一組用于保存Map里的key,另一組用于保存Map中的value,key和value都可以是任意引用類型數(shù)據(jù),其中,作為key的值是不允許重復(fù)的,而value中可以出現(xiàn)重復(fù)。Map : 維護(hù)“鍵值對”的關(guān)聯(lián)性,使你可以通過“鍵”查找“值”。 HashMap就是使用對象的hashCode()進(jìn)行快速查詢的。此方法能夠顯著提高性能。HashMap集合是基于哈希表的Map接口實(shí)現(xiàn),并允許使用null鍵null值,但必須保證鍵的唯一性。 LinkedHashMap : 類似于HashMap,但是迭代遍歷它時(shí),取得“鍵值對”的順序是其插入次序。而在迭代訪問時(shí)發(fā)而更快,因?yàn)樗褂面湵砭S護(hù)內(nèi)部次序。 TreeMap : 基于紅黑樹數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)。查看“鍵”或“鍵值對”時(shí),它們會(huì)被排序(順序由Comparabel或Comparator決定)。TreeMap的特點(diǎn)在于,你得到的結(jié)果是經(jīng)過排序的。 Hashtable線程安全,但是存取速度很慢,且不允許存放null鍵null值,目前基本上被hashMap類所取代。Hashtable有一個(gè)重要的子類Properties。 Properties:java.util.Properties;key和value都是String類型,用來讀配置文件。繼承自Hashtable,比 Hashtable 更嚴(yán)格 屬性列表中每個(gè)鍵及其對應(yīng)值都是一個(gè)字符串。常用方法 String getProperty(String?key)和 setProperty(String key,String value); 用法:我在D盤下建了一個(gè)名為 AA.dat 的文件,文件的內(nèi)容為: name=ch password=12345 執(zhí)行以下程序,輸出 ch,可見用 Properties 可以很方便的解析配置文件 Properties p = new Properties();p.load(new FileInputStream(“D:AA.dat”));System.out.println(p.getProperty(“name”)) 前言: 本文是對Java集合框架做了一個(gè)概括性的解說,目的是對Java集合框架體系有個(gè)總體認(rèn)識(shí),如果你想學(xué)習(xí)具體的接口和類的使用方法,請參看Java API文檔。 一、概述 數(shù)據(jù)結(jié)構(gòu)對程序設(shè)計(jì)有著深遠(yuǎn)的影響,在面向過程的C語言中,數(shù)據(jù)庫結(jié)構(gòu)用struct來描述,而在面向?qū)ο蟮木幊讨校瑪?shù)據(jù)結(jié)構(gòu)是用類來描述的,并且包含有對該數(shù)據(jù)結(jié)構(gòu)操作的方法。 在Java語言中,Java語言的設(shè)計(jì)者對常用的數(shù)據(jù)結(jié)構(gòu)和算法做了一些規(guī)范(接口)和實(shí)現(xiàn)(具體實(shí)現(xiàn)接口的類)。所有抽象出來的數(shù)據(jù)結(jié)構(gòu)和操作(算法)統(tǒng)稱為Java集合框架(Java Collection Framework)。 Java程序員在具體應(yīng)用時(shí),不必考慮數(shù)據(jù)結(jié)構(gòu)和算法實(shí)現(xiàn)細(xì)節(jié),只需要用這些類創(chuàng)建出來一些對象,然后直接應(yīng)用就可以了。這樣就大大提高了編程效率。 二、集合框架的層次結(jié)構(gòu) Collection是集合接口 |————Set子接口:無序,不允許重復(fù)。 |————List子接口:有序,可以有重復(fù)元素 區(qū)別:Collections是集合類 Set和List對比: Set:檢索元素效率低下,刪除和插入效率高,插入和刪除不會(huì)引起元素位置改變。 List:和數(shù)組類似,List可以動(dòng)態(tài)增長,查找元素效率高,插入刪除元素效率低,因?yàn)闀?huì)引起其他元素位置改變。 Set和List具體子類: Set |————HashSet:以哈希表的形式存放元素,插入刪除速度很快。 List |————ArrayList:動(dòng)態(tài)數(shù)組 |————LinkedList:鏈表、隊(duì)列、堆棧。 Array和java.util.Vector Vector是一種老的動(dòng)態(tài)數(shù)組,是線程同步的,效率很低,一般不贊成使用。 三、Iterator迭代器(接口) Iterator是獲取集合中元素的過程,實(shí)際上幫助獲取集合中的元素。 迭代器代替了 Java Collections Framework 中的 Enumeration。迭代器與枚舉有兩點(diǎn)不同: 迭代器允許調(diào)用方利用定義良好的語義在迭代期間從迭代器所指向的集合移除元素。方法名稱得到了改進(jìn)。 Iterator僅有一個(gè)子接口ListIterator,是列表迭代器,允許程序員按任一方向遍歷列表、迭代期間修改列表,并獲得迭代器在列表中的當(dāng)前位置。ListIterator 沒有當(dāng)前元素;它的光標(biāo)位置 始終位于調(diào)用 previous()所返回的元素和調(diào)用 next()所返回的元素之間。在長度為 n 的列表中,有 n+1 個(gè)有效的索引值,從 0 到 n(包含)。 四、集合框架之外的Map接口 Map將鍵映射到值的對象。一個(gè)映射不能包含重復(fù)的鍵;每個(gè)鍵最多只能映射一個(gè)值。Map接口是Dictionary(字典)抽象類的替代品。 Map 接口提供三種collection 視圖,允許以鍵集、值集合或鍵-值映射關(guān)系集的形式查看 某個(gè)映射的內(nèi)容。映射的順序 定義為迭代器在映射的 collection 視圖中返回其元素的順序。某些映射實(shí)現(xiàn)可明確保證其順序,如 TreeMap 類;某些映射實(shí)現(xiàn)則不保證順序,如 HashMap 類。 有兩個(gè)常見的已實(shí)現(xiàn)的子類: HashMap:基于哈希表的 Map 接口的實(shí)現(xiàn)。此實(shí)現(xiàn)提供所有可選的映射操作,并允許使用 null 值和 null 鍵。(除了不同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順序恒久不變。 TreeMap:它實(shí)現(xiàn)SortedMap 接口的基于紅黑樹的實(shí)現(xiàn)。此類保證了映射按照升序順序排列關(guān)鍵字,根據(jù)使用的構(gòu)造方法不同,可能會(huì)按照鍵的類的自然順序 進(jìn)行排序(參見 Comparable),或者按照創(chuàng)建時(shí)所提供的比較器進(jìn)行排序。 Hashtable:此類實(shí)現(xiàn)一個(gè)哈希表,該哈希表將鍵映射到相應(yīng)的值。任何非 null 對象都可以用作鍵或值。 五、線程安全類 在集合框架中,有些類是線程安全的,這些都是JDK1.1中的出現(xiàn)的。在JDK1.2之后,就出現(xiàn)許許多多非線程安全的類。 下面是這些線程安全的同步的類: Vector:就比ArrayList多了個(gè)同步化機(jī)制(線程安全)。 Statck:堆棧類,先進(jìn)后出。 Hashtable:就比HashMap多了個(gè)線程安全。 Enumeration:枚舉,相當(dāng)于迭代器。 除了這些之外,其他的都是非線程安全的類和接口。 線程安全的類其方法是同步的,每次只能一個(gè)訪問。是重量級對象,效率較低。對于非線程 安全的類和接口,在多線程中需要程序員自己處理線程安全問題。 六、其他一些接口和類介紹 Dictionary和Hashtable類: Dictionary提供鍵值映射的功能,是個(gè)抽象類。一般使用它的子類HashTable類。遍歷Hashtable類要用到枚舉。 Properties類 Properties 繼承于 Hashtable,Properties 類表示了一個(gè)持久的屬性集。Properties 可保存在流中或從流中加載。屬性列表中每個(gè)鍵及其對應(yīng)值都是一個(gè)字符串。一般可以通過讀取properties配置文件來填充Properties對象。第三篇:java集合總結(jié)
第四篇:黑馬程序員:Java集合簡單總結(jié)
第五篇:Java集合框架使用總結(jié)