java.util.List
接口繼承自 Collection
接口 ,是單列集合中的一個重要分支。java
方法 | 描述 |
---|---|
void add(int index, E element) | 將指定的元素插入此列表中的指定位置(可選操做)。 |
E get(int index) | 返回此列表中指定位置的元素。 |
E remove(int index) | 刪除該列表中指定位置的元素(可選操做)。 |
E set(int index, E element) | 用指定的元素(可選操做)替換此列表中指定位置的元素。 |
package collection; import java.util.ArrayList; import java.util.List; /** * 測試list接口的幾個特有方法 * 有序,與index相關的經常使用方法 */ public class TestList { public static void main(String[] args) { List<String> list = new ArrayList<>(); System.out.println(list); list.add("A"); list.add("B"); list.add("C"); System.out.println(list); list.add(1, "a"); System.out.println(list); System.out.println("刪除元素"+list.remove(0)); System.out.println(list); System.out.println("被替換的元素" + list.set(0, "A")); System.out.println(list); } }
結果數組
[] [A, B, C] [A, a, B, C] 刪除元素A [a, B, C] 被替換的元素a [A, B, C]
注意下標越界跟數組同樣安全
java.util.ArrayList 是可調整大小的數組的實現List接口網絡
元素增刪慢,查找快,知足平常開發中實現查詢數據、遍歷數據等功能框架
但不意味着隨意使用ArrayList完成任何需求,當頻繁增刪數據時,效率極低。工具
數據存放在Object類型的數組中:性能
transient Object[] elementData; // non-private to simplify nested class access
測試
既然是數組,那它是怎樣實現自動擴容的呢?this
以ArrayList 的add方法源碼舉例.net
// 在添加數據以前,確保容量充足 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } // 肯定具體容量 -> 計算容量 private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } // 若是列表爲空,返回默認容量 DEFAULT_CAPACITY = 10,不然返回最小容量 private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } // 若是最小容量小於數組長度,則給數組擴容 private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } // 擴容過程,舊容量 = 原數組長度,新容量 = 擴容1.5倍 // 若是新容量小於最小容量,新容量=最小容量 // 若是新容量 大於 最大數組大小 Integer.MAX_VALUE - 8 //總之用數組存儲是不可能無限增加,超過21億多就拋出內存溢出異常 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } // 最後調用工具類Arrays的複製方法,將原數組的數據複製到一個新的數組
Arrays.java
public static <T> T[] copyOf(T[] original, int newLength) { return (T[]) copyOf(original, newLength, original.getClass()); } 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; } // 底層仍是調用了系統級的複製數組方法
// 本地方法 public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
注意
ArrayList的實現不是同步的,存在線程安全問題。
用雙向鏈表存儲數據
private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
繼承 AbstractSequentialList 類
實現了不少接口
public class LinkedList<E>extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable{} public interface Deque<E> extends Queue<E> {}
Java LinkedList(鏈表) 相似於 ArrayList,是一種經常使用的數據容器。
與 ArrayList 相比,LinkedList 的增長和刪除對操做效率更高,而查找和修改的操做效率較低。
如下狀況使用 ArrayList :
如下狀況使用 LinkedList :
方法 | 描述 |
---|---|
void addFirst(E e) | 在該列表開頭插入指定的元素。 |
void addLast(E e) | 將指定的元素追加到此列表的末尾。 |
void push(E e) | 將元素推送到由此列表表示的堆棧上。 |
E getFirst() | 返回此列表中的第一個元素。 |
E getLast() | 返回此列表中的最後一個元素。 |
E peek() | 檢索但不刪除此列表的頭(第一個元素)。 |
E peekFirst() | 檢索但不刪除此列表的第一個元素,若是此列表爲空,則返回 null 。 |
E peekLast() | 檢索但不刪除此列表的最後一個元素,若是此列表爲空,則返回 null 。 |
E poll() | 檢索並刪除此列表的頭(第一個元素)。 |
E pollFirst() | 檢索並刪除此列表的第一個元素,若是此列表爲空,則返回 null 。 |
E pollLast() | 檢索並刪除此列表的最後一個元素,若是此列表爲空,則返回 null 。 |
E removeFirst() | 今後列表中刪除並返回第一個元素。 |
E removeLast() | 今後列表中刪除並返回最後一個元素。 |
E pop() | 今後列表表示的堆棧中彈出一個元素。 |
全部單列集合的祖先,Java 1.0版本就已經發布!
Java1.2版本以後,ArrayList取代了Vector。
Vector 類實現了一個動態數組。和 ArrayList 很類似,可是二者是不一樣的:
java.util.Set
接口繼承自 Collection
接口 ,也是單列集合中的一個重要分支。
java.util.HashSet
集合實現 Set
接口
HashTable 查詢速度很是快
public class HashSet<E>extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable{ static final long serialVersionUID = -5024744406713321676L; private transient HashMap<E,Object> map; // Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object(); /** * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has * default initial capacity (16) and load factor (0.75). */ public HashSet() { map = new HashMap<>(); } }
import java.util.HashSet; import java.util.Iterator; public class TestHashSet { public static void main(String[] args) { HashSet<String> set = new HashSet<>(); System.out.println(set.add("a")); System.out.println(set.add("a")); System.out.println(set.add("b")); System.out.println(set.add("c")); System.out.println("========迭代器======="); Iterator<String> it = set.iterator(); while (it.hasNext()) { System.out.print(it.next() + "\t"); } System.out.println("\n========加強for======="); for (String s : set) { System.out.print(s + "\t"); } } }
結果
true false true true ========迭代器======= a b c ========加強for======= a b c
一個十進制的整數,由系統隨機給出。
能夠視爲模擬對象存儲的邏輯地址,而不是數據實際存儲的物理地址。
Object祖宗類中就提供獲取hash值的方法hashCode() ,hashCode調用了
public native int hashCode();
對具體實現感興趣的請轉至傳送門
哈希碼的通用約定以下:
查詢快!
JDK 1.8 以前,哈希表 = 數組 + 鏈表
JDK 1.8 以後
數組結構:把元素分組,相同哈希值的放到一塊兒,用鏈表或紅黑樹保存
當鏈表長度超過8位,將鏈表轉爲紅黑樹
初始容量爲16
存儲數據到集合的過程
就是HashMap !!
http://www.javashuo.com/article/p-memupmkd-bc.html
HashMap明天再補