集合①只能存放對象,存放基本類型會自動轉成對應的對象②能夠存放不一樣類型的對象(若是不使用泛型的話),且不限數量③集合中存放的只是對象的引用
集合詳解
html
Collection繼承了該接口,因此Collection的實現類均可以使用Iterator()
方法來得到迭代器,從而遍歷集合java
public interface Iterable<E> { Iterator<E> iterator();//return a Iterator Object }
迭代器可使用for-each代替。迭代器至關於一個在兩個元素之間的指針(首尾元素除外),使用remove()
刪除元素以前,須要先調用next()
越過該元素。若是調用next()
以後,集合發生了改變,再接着調用remove()
則會拋出異常。算法
public interface Iterator<E>{ E next();//返回迭代器剛越過的元素的引用 boolean hasNext();//判斷容器內是否還有可供訪問的元素 void remove();//刪除迭代器剛越過的元素,因此要刪除則必須先越過 }
ListIterator接口繼承了Iterator接口,並添加了一些方法,使得能夠向前和向後遍歷。數組
add set//修改越過的元素 previous hasPrevious nextIndex//返回下一次調用next方法返回的元素的索引 previousIndex
獲取迭代器默認其指針是在第一個元素的前面,能夠經過給定一個參數n來指定指針位置爲第n個元素的前面(ListIterator有,Iterator沒有這個),不過獲取這樣的迭代器消耗的時間比默認狀態的迭代器要高一些。另外須要注意的是remove依賴迭代器的狀態,add只依賴迭代器的位置安全
Collection接口定義了不少方法,開發者若是要開發本身的集合類,能夠繼承AbstractCollection抽象類,該類實現了Collection的不少方法,可是還有size()
和Iterator()
沒實現數據結構
方法 | 描述 |
---|---|
iterator() |
獲取迭代器 |
size() |
元素個數 |
isEmpty() |
判斷有無元素 |
clear() |
清空集合 |
contains() |
是否包含給定元素 |
containsAll() |
是否包含給定集合全部元素 |
add() |
添加元素 |
addAll() |
添加給定集合全部元素 |
remove() |
刪除元素 |
removeAll() |
刪除給定集合中全部元素 |
retainAll() |
刪除給定集合中不存在的元素,即取交集 |
toArray() |
返回集合的對象數組 |
toArray(array) |
同上,不過指定一個數組參數 |
List能夠得到ListIterator迭代器,List能夠有重複的元素,元素能夠按照使用者的意願排序,元素的位置跟元素的值沒有關係,所以稱爲有序ide
addFirst addLast getFirst getLast removeFirst removeLast
Set不能夠有重複的元素,只能用Iterator迭代器,不能使用ListIterator迭代器性能
LinkedHashSet
不能夠重複,判斷重複的標準是equals爲true,且hashCode相等,有序(記錄了插入順序)。由於底層採用鏈表和哈希表的算法。鏈表保證元素的添加順序,哈希表保證元素的惟一性this
隊列能夠有效的在隊列尾部添加元素,頭部刪除元素。雙端隊列能夠同時在尾部和頭部添加和刪除元素,不過不能夠在中間。ArrayDeque和LinkedList實現了雙端隊列spa
底層數據結構是堆(heap)。典型示例爲任務調度。優先級隊列跟TreeSet同樣,須要元素實現Comparable接口或在構造時提供Comparator比較器。不管以什麼順序插入,remove()的老是優先級隊列裏最小的元素,然而優先級隊列並無對全部元素進行排序,只是確保了remove出來的是最小的元素
映射表存儲的是鍵值對,Map不能使用for-each循環進行遍歷,由於它既不是Collection系列,也沒繼承Iterable接口
//Map的方法 put get putAll containsKey containsValue Set<Map.Entry<K,V>> entrySet()//後面3個方法返回的是Map的視圖,能夠經過這三個集修改和刪除元素,則Map中也會相應改變,可是不能添加元素 Set<K> keySet() Collection<V> values() //Entry的方法 getKey getValue setValue
HashMap
對鍵進行散列,鍵不容許重複,容許爲null(最多一個),判斷鍵重複的標準是鍵的equals爲true,且鍵的hashCode相等
TreeMap
對鍵進行排序,用鍵的順序對元素進行排序,鍵不容許重複,判斷鍵重複的標準是鍵compareTo或compare爲0
LinkedHashMap
與HashMap相似,只是多了鏈表保證鍵有序(記錄了訪問順序,每次因調用了get/set方法受到影響的元素都會從當前鏈表位置刪除,放到鏈表末尾,但注意在桶中的位置是不會受影響的)
WeakHashMap
弱散列映射表
Hashtable
與HashMap同樣,不過線程安全,性能低
Properties
Hashtable的子類,要求鍵值都是字符串,通常用於配置文件
都有幾個類型的集合。HashMap 和 HashSet ,都採哈希表算法;TreeMap 和 TreeSet 都採用 紅-黑樹算法;LinkedHashMap 和 LinkedHashSet 都採用 哈希表算法和紅-黑樹算法。分析 Set 的底層源碼,咱們能夠看到,Set 集合 就是 由 Map 集合的 Key 組成,只不過Value是同一個Object對象
Arrays.asList()
String[] strs = new String[10]; List<String> list = Arrays.asList(strs);//list是原數組的視圖
集合轉數組
toArray(數組)
HashSet<String> staff = new HashSet<>(...); String[] strs = staff.toArray();//error String[] strs = staff.toArray(new String[0]);//ok String[] strs = staff.toArray(new String[staff.size()]);//ok
int[] a1 = {1, 3}; int[] a2 = a1.clone(); a1[0] = 666; System.out.println(Arrays.toString(a1)); //[666, 3] System.out.println(Arrays.toString(a2)); //[1, 3] String[] s1 = {"a1", "a2"}; String[] s2 = s1.clone(); a1[0] = "b1"; //更改a1數組中元素的值 System.out.println(Arrays.toString(s1)); //[b1, a2] System.out.println(Arrays.toString(s2)); //[a1, a2]
System.arraycopy
System.arraycopy是一個本地方法,源碼定義以下
public static native void arraycopy(Object src, int srcPos, Object dest, int desPos, int length) //參數含義(原數組, 原數組的開始位置, 目標數組, 目標數組的開始位置, 拷貝長度)
Arrays.copyOf
Arrays.copyOf底層其實也是用的System.arraycopy ,參數含義(原數組,拷貝長度)源碼以下:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
Arrays.copyOfRange
Arrays.copyOfRange底層其實也是用的System.arraycopy,只不過封裝了一個方法,參數含義(原數組,開始位置,拷貝長度)
public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) { int newLength = to - from; if (newLength < 0) throw new IllegalArgumentException(from + " > " + to); @SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength)); return copy; }
@Override public Cat clone() throws CloneNotSupportedException { Cat cat = (Cat) super.clone(); return dog; }
public Cat myClone() { Cat cat = null; try { //將對象序列化成爲流,由於如今流是對象的一個拷貝 //而原始對象仍然存在於JVM中,因此利用這個特性能夠實現深拷貝 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(this); //將流序列化爲對象 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); cat = (Cat) objectInputStream.readObject(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } return cat; }