*視圖與包裝器 和 批操作 兩節沒怎么看
1.Collection 接口 中至少包含add和iterator方法,使用add方法時不允許添加已經存在的對象(添加失敗時add方法會返回false,否則返回true)。Iterator接口中包含next,hasNext, remove 方法。
2.實現了 Iterable接口 的集合才可以使用for each進行遍歷。而Collection接口擴展了Iterable接口,所以所有的標準類庫中的集合都可以使用for each來進行遍歷
3.應該認為java的迭代器是位于兩個元素之間的位置。每次調用next方法,就越過一個元素,next方法會返回剛剛越過的那個元素。
4.Iterator的next方法和remove方法是相互依賴的。在調用remove方法之前必須先調用next方法。如:
Iterator<String> it = c.iterator(); //c在這里是一個集合it.next();it.remove(); //此時刪掉了剛剛越過的那個元素it.next(); //如果想要刪掉兩個相鄰的元素,也必須兩次調用next方法it.remove();5.AbstractCollection實現了更多常用的方法,如contains方法(判斷依據是equals,不是==)。
6.標準庫中,以Map結尾的集合實現的是Map接口,而不是Collection接口。
7.具體的集合 (1)鏈表 [1]Java中的鏈表(LinkedList)都是雙向鏈表,每個結點存放著前一個和后一個結點的引用。 [2]鏈表與泛型集合的一個重要區別是鏈表是一個有序集合,每個對象的位置十分重要。 [3]依賴于位置的add方法(比如添加一個元素到某個具體的位置)由迭代器進行負責。插入時,迭代器位于哪個位置,就會將元素插入到哪個位置。 [4]上面提到的add方法存在于ListIterator接口中,這個接口中還包含PRevious和hasprevious方法,用來反向遍歷鏈表。 [5]在調用previous方法之后也可以調用Iterator的remove方法,刪除的是剛剛越過的那個結點。 [6]ListIterator中的add方法依賴于迭代器的位置,Iterator中的remove方法依賴于迭代器的狀態。 [7]一個迭代器在訪問集合時,如果發現集合被另一個迭代器修改了,就會拋出一個ConcurrentModificationException異常。但是僅限于添加、刪除元素的 結構性修改,即如果使用set修改則不會拋出異常 [8]LinkedList類提供了一個用于訪問某個特定元素的get方法,但是應該避免使用這個方法。同時也要避免使用以整數索引表示鏈表中位置的所有方法。(想要使用整數索引來訪問的話,完全可以用ArrayList,沒必要用LinkedList) [9]ListIterator中還包含nextIndex和previousIndex方法用來返回迭代器所在位置的下一個元素的索引和上一個元素的索引(注意迭代器是位于元素之間的) [10]list.ListIterator(n)將返回一個迭代器,這個迭代器指向索引為n的元素前面(左邊)的位置。但是效率比較低。 (2)數組列表(ArrayList):在不需要同步時使用ArrayList類,需要同步時(如兩個線程安全的訪問同一個對象)使用Vector類。 (3)散列集:使用散列碼來查找集合中的元素,但是無法控制元素出現的順序。 [1]使用數組來進行存儲,數組中的每個元素(稱為桶)又是一個鏈表,鏈表(桶)用來存放散列值相同(沖突)的元素。 [2]set類型(如HashSet)就是使用散列表實現的。其中的add方法會先檢查是否已經存在該對象。 [3]HashSet的contains方法已經被重寫,不必每個元素都查看,可以根據散列碼直接定位到對應的桶。(但是還是使用equals判斷是否已經存在) (4)樹集(TreeSet):可以對添加到里面的元素自動進行排序。 [1]將一個元素添加到樹集中,要比添加到散列集中慢,但是比添加到ArrayList或者LinkedList中要快。 [2]一般情況下,實現Comparable接口使用compareTo方法比較對象之間的大小。但是,有時,比如兩組TreeSet對象的比較標準不一樣(當然兩組是各自比較各自的),就不能使用Comparable了。這時,可以使用Comparator接口,將其傳遞給TreeSet的構造器,如:
TreeSet<Item> itemTreeSet = new TreeSet<>( new Comparator<Item>(){ //只是作為函數對象(沒有任何數據,只是作為比較方法的持有器),一般使用匿名內部類 public int compare(Item a, Item b){ String descrA = a.getDescription(); Stirng descrB = b.getDescription(); return descrA.compareTo(descrB); } });(5)隊列(Queue)(尾部添加,頭部刪除)與雙端隊列(頭部尾部都可以添加刪除):ArrayDeque(循環數組隊列)和LinkedList(鏈表隊列)實現了Deque接口,且都提供了雙端隊列。(deque的意思就是雙端隊列) (6)優先級隊列(PriorityQueue):使用堆實現。與TreeSet一樣,既可以保存實現了Comparable接口的類對象,也可以保存在構造器中提供比較器的對象。 注意:優先級隊列不一定保證所有元素都是按序排列的,但是它能夠保證隊列的頭一定是最小的元素(調用PriorityQueue的remove方法時刪除的一定是最小的),這是TreeSet和PriorityQueue的區別 (7)映射表(Map) [1]HashMap和TreeMap實現了Map接口,在需要排序時使用TreeMap,不需要排序時使用HashMap。 [2]散列或者比較函數只能作用于鍵。 [3]put函數用來向map中添加鍵值對,如果對同一個鍵兩次調用put方法,第二個值就會取代第一個值,而put函數會返回第一個值。 [4]三個視圖:Set keySet()(既不是HashSet,也不是TreeSet) , Collection values() , Set
for(Map.Entry<String, Employee> entry : staff.entrySet()) //staff是一個HashMap對象 { String key = entry.getKey(); Employee value = entry.getValue(); ... }(8)專用集與映射表集 [1]如果程序中對某個鍵的最后一次引用已經消亡,垃圾回收器此時卻不能夠回收該對象。(因為映射表對象是活動的,所以其中的所有桶也都是活動的,垃圾回收器不能回收活動的對象)WeakHashMap就是用來解決這一問題。 [2]LinkedHashSet和LinkedHashMap,使用鏈表將各個桶中的元素鏈接起來,最近一次操作的元素將被放在鏈表的尾部,也就是說,是按照元素的訪問次序來對元素進行排序。(對于最近最少使用原則非常有用,比如內存滿了,可以直接將頭部的元素刪掉,然后添加新的元素) [3]IdentityHashMap,鍵的散列值不使用hashCode方法,而是使用System.identityHashCode方法計算的,即根據對象的內存地址來計算散列碼。而且,在對對象進行比較時,使用==,而不是equals
8.(1)將數組轉化為一個集合: String[] values = …; HashSet staff = new HashSet<>(Arrays.asList(values)); //Arrays.asList方法返回一個包裝了普通數組的List包裝器 (2)將集合轉為一個數組: String[] values = (String[])staff.toArray(); //將會出錯,因為toArray方法返回的是一個重新構造的Object類型的數組,無法轉換為String類型 可以使用另一個toArray方法: String[]values = (String[])staff.toArray(new String[0]); //正確。這個toArray方法同樣也是返回一個Object類型的數組,但是在構造時是根據toArray方法參數的類型構造的,所以可以進行轉化
9.**Collection中包含靜態方法**sort和shuffle,還有binarySearch方法(先檢查要排序的集合是否實現了Randomaccess接口,如果實現了就采用二分查找,否則采用線性查找。另外,如果查找不到某個元素,方法將返回一個負值,這種情況下應該將鍵插入到-i-1的位置)
10.遺留的集合 (1)Hashtable(小寫t)與HashMap的作用一樣,他們擁有相同的接口。Hashtable和Vector的方法都是同步的,HashMap則不是。如果對同步性和遺留代碼沒有任何要求,那么就使用HashMap。 (2)Enumeration接口,包含兩個方法hasMoreElements和nextElement。另外,靜態方法Collection.enumeration方法將產生一個枚舉對象。
Enumeration<Employee> e = staff.elements();while(e.hasMoreElements()){ Employee ee = e.nextElement(); ...}(3)屬性映射表(Properties類實現了Java的屬性映射表):[1]通常用于程序的特殊配置選項。[2]鍵和值都是字符串。[3]表可以保存到文件中,也可以從文件中加載。[4]使用一個默認的輔助表。 (4)Stack類包含pop和push方法。但是Stack類擴展為Vector類,可以讓棧使用不屬于棧操作的insert和remove方法(這點并不讓人滿意)。 (5)位集(BitSet):用于存放一個位序列,要比使用Boolean對象的ArrayList更加高效。get方法獲取某一位的狀態,set方法將某一位設置為true,clear方法將某一位設置為false
新聞熱點
疑難解答