集合概览
在網上找了個集合類圖,在此表示感謝原作者:
1.Set
Set集合不允許包含相同的元素,如果試圖把兩個相同元素加入同一個集合中,add方法返回false。
Set判斷兩個對象相同不是使用==運算符,只要兩個對象用equals方法比較返回true就是重復。
從Java源碼來看,Java是先實現了Map,然后通過包裝一個value都為null的Map就實現了Set集合。
1.1 HashSet
HashSet集合中,當hashCode()返回值相等,且equals()方法也相等的兩個元素才叫重復。
HashSet速度快的原因:
hash算法的價值在于速度,當需要查詢集合中某個元素時,hash算法可直接根據該元素的hashcode值計算出該元素的存儲位置
HashSet特性:
不是線程同步的
不能保證元素的插入順序,順序有可能發生變化
存儲的元素可以是null,但只能放入一個null
1.2 TreeSet
TreeSet支持兩種排序方式,自然排序 和定制排序。
自然排序(默認排序方式):
使用要排序元素的CompareTo(Object obj)方法來比較元素之間大小關系,然后將元素按升序排列。如:
obj1.compareTo(obj2)方法如果返回0,則說明被比較的兩個對象相等,如果返回一個正數,則表明obj1大于obj2,如果是 負數,則表明obj1小于obj2。
TreeSet判斷兩個對象是否相等的唯一標準是:這兩個對象的compareTo方法返回結果為0
定制排序:
參考:http://blog.csdn.net/zcl_love_wx/article/details/60757075
注:
TreeSet在添加第一個元素時,由于不會與其他任何元素進行比較,所以不會實現Comparable接口,只有在添加后續的元素時,才會實現Comparable接口,然后調用compareTo方法比較,然后按升序排列。
如果希望TreeSet能正常運作,所有元素只能是同一種數據類型。
1.3 LinkedHashSet
1.4 總結
只有當一個集合需要保持順序時,才應該用TreeSet,否則都應該用HashSet
2. List
List判斷兩個對象的相等條件是,equals()方法的返回值為true
2.1 ArrayList和Vector幾個常見方法
addAll(int index,Collection c):將集合c插入到List集合的index索引處
set(int index,Object o):將集合中index索引處的元素替換為o,并返回舊元素。
subList(int from,int to):返回從from到to(不包含)的子集合。
其實大多數截取從一個索引到另一個索引的所有值,都是不包含后一個索引的值的。最初我一直記不清楚,后來發現,如果兩個索引的值都包含的話,我們將永遠不能做到只取一個值的情況。
replaceAll(UnaryPerator uo):根據uo指定的計算規則,重新設置List集合
sort(Comparator c):根據自定義的比較器指定的計算規則對List排序。
2.2 ArrayList和Vector集合的listIterator()方法返回一個ListIterator對象,擴展了操作集合的方法:
hasPrevious():是否有上一個元素
previous():返回上一個元素
add(String e):添加一個元素。Iterator就不可以。
ListIterator和Iterator都有hasNext()和next()方法,可以實現順序向后遍歷。但是ListIterator有hasPrevious()和previous()方法,可以實現逆向(順序向前)遍歷。nextIndex()和previousIndex()方法可以定位當前元素的索引位置。Iterator就不可以。
2.3 ArrayList、Vector、LinkedList的區別
2.4 Stack類
Stack繼承自Vector,實現一個后進先出的堆棧。Stack提供5個額外的方法使得Vector得以被當作堆棧使用。
peek():返回棧頂第一元素,但并不彈出。
pop():返回棧頂第一個元素,并彈出。
push(Object o):將元素加入棧頂。
empty方法測試堆棧是否為空
search方法檢測一個元素在堆棧中的位置。
Stack剛創建后是空棧。
2.5 固定長度的List
Arrays類的asList(Object … a)方法,可以將一個數組轉成一個List集合,而該集合既不是ArrayList的實現類,也不是Vector的,而是Arrays的內部類ArrayList的實例。Arrays.ArrayList是一個固定長度的List集合,程序只能遍歷該集合,不能進行增、刪操作。
2.6 使用List集合建議
對于ArrayList 和Vector集合使用get(i)遍歷
對于LinkedList集合使用Iterator遍歷
3. Queue集合
4. 線性表性能分析
數組是以一塊連續內存區來保存所有元素的容器。對于所有內部基于數組的集合實現(如ArrayList、Vector),使用隨機訪問的性能比使用Iterator迭代訪問要好,因為隨機訪問會被映射成對數組的訪問。但插入和刪除數據時涉及到數組元素移動等內存操作,所以相對來說就慢。
5. 操作集合的工具類:Collections
5.1 對List集合元素進行排序
reverse(List list) 反轉指定的list集合
sort(List list) 按自然排序將list排序
sort(List list,Comparator c) 按排序器c指定的規則將list進行排序
swap(List list ,int i , int j) 將list集合中索引為i與j的元素對調交換
5.2 查找、替換的方法
int binarySearch(List list, Object key):二分法搜索key對應的元素在list里的索引。前提是list已經有序。
Object max(Collection c):返回集合中最大元素。按自然排序的結果。返回最小元素一樣。
Object max(Collection c,Comparator comp):按給定的排序規則返回最大元素。返回最小元素一樣。
void fill(List list,Object obj):用obj替換list的所有元素
int frequency(Collection c,Object o):o在c中出現的次數
int indexOfSubList(List source,List target):返回target子集在source中第1次出現的索引,沒有返回-1
int lastIndexOfSubList()List source,List target):返回target子集在source中最后一次出現的索引,沒有返回-1
boolean replaceAll(List list,Object oldVal,Object newVal):用newVal替換list中的所有oldVal
5.3 同步控制:SynchronizedXxx()方法
Java集合中,HashSet、TreeSet、HashMap、TreeMap、ArrayList、LinkedList、ArrayDeque等 都是線程不安全的,可通過SynchronizedXxx方法包裝成線程安全的集合,如:
Collection c = Collections.synchronizedCollection(new ArrayList<>()); List list = Collections.synchronizedList(new ArrayList()); Set set = Collections.synchronizedSet(new HashSet()); Map map = Collections.synchronizedMap(new HashMap<>());6. Map
6.1. Map常見方法
keySet():返回Map集合里所有key組成的Set集合
entrySet():返回Map中所有Entry對象組成的set集合,Entry是Map的內部類。
forEach(BiConsumer action):Java8新增遍歷Map的方法
6.2. Entry這個內部類,封裝了一個key-value對,介紹其如下三個方法:
Object getKey():返回Entry里包含的key值
Object getValue():返回Entry里包含的value值
Object setValue(V value):設置Entry里包含的value,并返回新設的值
6.3 TreeMap
如果程序需要一個總是排好序的Map時,則應該考慮用TreeMap
TreeMap和TreeSet有很多類似之處
6.4 HashMap
6.5LinkedHashMap
LinkedHashMap也使用雙端鏈表來維護key-value對的次序,和linkedHashSet一樣也維護了插入順序,所以迭代也快。
6.6 WeakHashMap
WeakHashMap中只保留了對實際對象的弱引用;
如果WeakHashMap中的key所引用的對象沒有被其他強引用變量所引用,則這些key所引用的對象可能被垃圾回收,WeakHashMap也可以自動刪除這些key所對應的key-value對。
6.7 Properties
Properties相當于一個key、value都為String類型的Map
Properties類可以把鍵值對和屬性文件關聯起來,從而可以key-value對寫入屬性文件,也可以把屬性文件中的”屬性名=屬性值”加載到Properties對象中。
Properties修改key、value的方法:
String getProperty(String key ):獲取Properties中key對應的value
setProperty(String key,String value):給Properties設置鍵和值
讀寫屬性文件的方法:
void load(InputStream in):從屬性文件中加載所有key-value對到Properties里
void store(OutPutStream out, String comments):將Properties中的key-value對輸出到指定的屬性文件中
示例:
Properties outP = new Properties(); outP.setProperty("username", "peter"); outP.setProperty("password", "123456"); //將兩個key-value對添加到a.txt屬性文件中 outP.store(new FileOutputStream("a.txt"), "備注信息");Properties inP = new Properties(); //將屬性文件加載到Properties里 inP.load(new FileInputStream("a.txt")); System.out.println(inP.getProperty("username"));6.8 Map性能分析
HashMap是為快速查詢設計的,其實現原理是利用key的hash值快速定位到value值在hash表的位置。但HashMap底層是采用數組來存儲key-value對。所以在使用containsKey(Object key)或containsValue(Object val)時只能通過遍歷數組來查詢。
TreeMap存儲數組的結構是二叉樹,所以在使用containsKey(Object key)或containsValue(Object val)時都是二分查詢,要快于HashMap的這兩個操作。
Hash表里可以存儲元素的位置被稱為桶(bucket)。通常桶里只存一個元素,此時有最好的性能。hash算法可根據hashCode值計算出“桶”的存儲位置,接著從桶中取出元素。當發生hash沖突時,一個桶會存儲多個元素,它們以鏈表形式存儲,且必須安順序搜索。
hash屬性:
1. 容量:hash表中桶的數量
2. 尺寸:當前hash表中記錄的數量
3.負載因子:尺寸/容量。為0時 表示空hash表;為0.5時 表示半滿的hash表
輕負載的hash表沖突少,適宜插入、查詢,但用Iterator迭代慢。
較高的負載極限可降低hash所占內存空間,但會增加查詢時間。
默認負載極限為:0.75
7. Java 并發工具包 java.util.concurrent
總結
- 上一篇: mysql计算某一天所在周或月的第一天和
- 下一篇: TreeSet的定制排序