集合類的由來:
對象用於封裝特有數據,對象多了需要存儲,如果對象的個數不確定。
就使用集合容器進行存儲。
集合特點:
1,用於存儲對象的容器。
2,集合的長度是可變的。
3,集合中不可以存儲基本數據類型的值。
集合容器因為內部的數據結構不同,有多種具體容器。
不斷的向上抽取,就形成了集合框架。
框架的頂層是Collection接口,定義了集合框架中共性的方法.
Collection的常見方法:
1,添加
boolean add(E e);
boolean addAll(Collection<? extends E> c)
2,刪除
boolean remove(E e);
boolean removeAll(Collection<?> c) ;
void clear();
3,判斷
boolean contains(Object o)
boolean containsAll(Collection<?> c)
boolean isEmply();
4,獲取
int size();
Iterator<E> iterator();
5,其他
boolean retainAll(Collection coll);
Object[] toArray();
Collection下常用的子接口:
List:有序(存入與取出的順序一致),元素都有索引(角標),元素可以重復。
Set: 元素不能重復,無序。
List特有常見方法:
有一個共性特點就是都可以操作角標。
1,添加
void add(index,element);
void add(index,collection);
2,刪除
Object remove(index);
3,獲取
Object get(index);
int indexOf(object);
int lastIndexOf(object);
Last subList(from,to);
4,修改
Object set(index,element);
ListIterator迭代器可實現對list集合進行增刪改查。
List集合常用實現子類:
Vector:內部是數組數據結構。是同步的。(幾乎不怎麼用,但是比較特殊),可變數組,100%延長。
增刪,查詢都很慢。
ArrayList:內部是數組數據結構,是不同步的。替代了Vector。
如在多線程中,一般采用ArrayList加鎖的形式實現。
可增長數組,50%延長。
查找元素的速度很快。
LinkedList:內部是鏈表數據結構,非同步的。增刪元素的速度很快。
LinkedList新老方法對比:
addFirst();
addLast();
jdk1.6
offerFirst();
offerLast();
getFirst();//獲取但不移除,如果鏈表為空,拋出NoSuchElementExcetion
getLast();
jdk1.6
peekFirst();//獲取但不移除,如果鏈表為空,返回null
peekLast();
removeFirst();//獲取並移除,如果鏈表為空,拋出NoSuchElementExcetion
removeLast();
jdk1.6
pollFirst(); 獲取並移除此列表的第一個元素;如果此列表為空,則返回
null
。
pollLast();
Set :元素不可以重復,是無序的。
Set接口中的方法和Collection中的一致。
常用子類:
HashSet:內部數據結構是哈希表,是不同步的,存儲元素的時候,使用的是元素的hashCode方法來確定位置,如果位置相同,再通過元素的equals方法來確定內容是否相同。
哈希表判定元素是否相同
1,判斷的是兩個元素的哈希值是否相同,如果相同,再判斷兩個對象的內容是否相同。
2,判斷哈希值相同,其實判斷的是對象的hashCode得方法,判斷內容相同,用的是equals方法。
注意:如果哈希值不同,是不需要判斷equals的。
LinkedHashSet:這個可以是有序的,與鏈表結合使用。
TreeSet:可以對Set集合中的元素進行排序,是不同步的。
判斷元素唯一性的方式:就是比較方法的返回結果是否是0,是0就是相同的元素。compareTo方法比較。
TreeSet對元素進行排序的方式一:
讓元素自身具備比較功能,元素就需要實現Compareable方法覆蓋compareTo方法。
如果不要按照對象中具備的自然順序進行排序,如果對象中不具備自然順序,即這個對象不是我們自己定義的。那麼我們可以使用TreeSet集合中的第二種排序方式:
讓集合自身具備比較功能,定義一個類實現Comparator接口,覆蓋compare方法。
將該類的對象作為參數傳遞給TreeSet集合的構造函數。
泛型
jdk1.5出現的安全機制。
好處:
1、將運行時期的問題ClassCastException轉換成編譯時的問題。
2、避免了強制換換的麻煩。
<>的應用場景:當操作的引用數據類型不確定的時候。就使用<>將要操作的引用數據類型傳入即可。其實<>就是一個用於接收具體引用數據類型的參數范圍。
在程序中,只要用到了帶有<>的類或者接口,就要明確傳入的具體引用數據類型。
泛型技術是給編譯器使用的技術,用於編譯時期,確保了類型的安全。
運行時,會將泛型去掉,生成的class文件中是不帶泛型的。
生成的class文件中不帶泛型的原因是為了兼容運行的類加載器。
泛型的補償:在運行時,通過獲取元素的類型進行轉換動作。不用使用者在強制轉換了。
在jdk1.5後,使用泛型來接收類中藥操作的引用數據類型。
當類中操作的引用數據類型不確定的時候,我們就使用泛型來表示。
注:當方法靜態時,不能訪問類上定義的泛型。如果靜態方法使用泛型,只能將泛型定義在方法上。將泛型定義在方法上時,必須要聲明在返回值類型的前面。
例:public static <T> void method (Y y){}
泛型的通配符:?代表的是未知的類型。
可以對類型進行限定:
? extends E : 接收E類型或者E的子類型。上限
? super E : 接收E類型或者E的富類型。下限
一般在存儲元素的時候我們都是使用上限,因為這樣取出都是按照上限類型來運算的,不會出現類型安全隱患。
一般我們對集合中的元素進行取出操作時,我們一般使用下限。
Map:一次添加一對元素。Collection是一次添加一個元素。
Map集合也稱為雙列集合,Collection集合稱為單列集合。
其實Map集合存儲的就是鍵值對。
Map集合必須保證鍵的唯一性。
常用方法:
1,添加
value put(key,value):返回前一個和key關聯的值,如果沒有則返回null
2,刪除
void clear():清空map集合。
value remove(key):根據指定的key刪除這個鍵值對
3,判斷
boolean containKey(key)
boolean containValue(value)
boolean isEmpty();
4,獲取
value get(key);通過鍵獲取值,如果沒有該鍵返回null
當然可以通過返回null來判斷是否包含指定鍵
int size()獲取鍵值對個數。
取出Map集合中的所有值的方法
方法一:原理就是通過keySet方法獲取map中所有的鍵所在的Set集合,再通過Set的迭代器獲取到每一個鍵,再對每一個鍵獲通過map集合的get方法取其對應值即可。
方法二:通過map集合的entryset方法也可取出map集合當中所有的鍵值對,返回的就是Map.Entry對象,再通過Map.Entry對象的getkey和getvalue方法就可以取出對應的鍵和值。
方法三:通過map集合的values方法也可獲取所有值。
Map集合常用的子類:
Hashtable:內部結構是哈希表,是同步的。不允許null作為鍵,null做為值
Hashtable子類:Propertise:用來存儲鍵值對型的配置文件的信息,可以和IO技術相結合。
HashMap:內部結構是哈希表,不是同步的。允許null作為鍵,null做為值
TreeMap:內部結構是二叉樹,不是同步的,可以對Map集合中的鍵進行排序。
集合的一些技巧:
需要唯一時用Set
且需要指定順序時:TreeSet
不需要指定順序時:HashSet
但是想要一個和存儲一致的順序(有序):LinkedHashSet
不需要唯一時用List
需要頻繁增刪動作
需要:LinkedList
不需要:ArrayList
如何記錄每一個容器的結構和所屬體系:
最簡單的就是看名字。
List
--ArrayList
--LinkedLst
Set
--HashSet
--TreeSet
後綴名就是該集合所屬的體系。
前綴名就是該集合所屬的數據結構。
看到array:想到的就是數組,查詢速度快。因為有角標是連續的內存地址。
看到link:想到的就是鏈表,增刪動作的速度快,而且要想到add get remove+first/last的方法
看到hash:想到的就是哈希表,那麼就具有唯一性,而且要想到元素需要覆蓋hashcode方法和equals方法
看到tree:想到的就是二叉樹,接下來想到的就是排序,然後就是兩個接口Comparable,Comparator
而且通常這些常用的集合容器都是不同步的。
Java多線程從簡單到復雜 http://www.linuxidc.com/Linux/2014-07/104435.htm
Java多線程經典案例 http://www.linuxidc.com/Linux/2014-06/103458.htm
Java多線程:ReentrantReadWriteLock讀寫鎖的使用 http://www.linuxidc.com/Linux/2014-06/103457.htm
Java內存映射文件實現多線程下載 http://www.linuxidc.com/Linux/2014-05/102201.htm
Java多線程:一道阿裡面試題的分析與應對 http://www.linuxidc.com/Linux/2014-03/98715.htm
Java中兩種實現多線程方式的對比分析 http://www.linuxidc.com/Linux/2013-12/93690.htm