Java 集合與容器類


Java 集合與容器類

體系

早在 Java 2 中之前,Java 就提供了特設類。比如:Dictionary, Vector, Stack 和 Properties 這些類用來存儲和操作對象組。雖然這些類都非常有用,但是它們缺少一個核心的,統一的主題。由於這個原因,使用 Vector 類的方式和使用 Properties 類的方式有着很大不同。為此,整個集合框架就圍繞一組標准接口而設計。

集合框架被設計成要滿足以下幾個目標。

  • 該框架必須是高性能的。基本集合(動態數組,鏈表,樹,哈希表)的實現也必須是高效的。
  • 該框架允許不同類型的集合,以類似的方式工作,具有高度的互操作性。
  • 對一個集合的擴展和適應必須是簡單的。
graph LR Collection接口-->List接口 Map接口-->HashMap類 Collection接口-->Set接口 List接口-->ArrayList類 List接口-->LinkedList類 Set接口-->HashSet類 Set接口-->SortedSet類 Map接口-->SortedMap類 SortedMap類-->TreeMap類 HashSet類-->LinkedHashSet類 SortedSet類-->Treeset類 Iterator接口-->ListIterator接口

接口

Collection

  1. 最基本的集合接口,存儲一組不唯一、無序的對象

  2. 公共方法

    方法 描述
    int size() 返回元素個數
    boolean isEmpty() 判斷是否為空
    boolean contains(Object obj) 判斷是否包含 obj
    boolean add(E element) 添加元素,返回成功與否
    int hashCode() 返回哈希碼
    Object[] toArray() 轉換為 Object 數組
    boolean remove(Object obj) 刪除元素
    void clear() 清空容器
    Iterator iterator 返回迭代器
    boolean equals(Object o) 是否與 o 相等
    void shuffle(List< ? > list) 隨機重排元素
    boolean containsAll(Collection< ? > c) 判斷是否包含 c 中所有元素
    boolean addAll(Contain< ? > c) 集合並運算
    boolean removeAll(Collection< ? > c) 集合差運算
    boolean retainAll(Collection< ? > c) 集合交運算,只保留也被 c 包含的元素

Map

  1. 存儲鍵值對,提供 key 到 value 的映射,key唯一

  2. 公共方法

    方法 描述
    V put(K key,V value) 插入鍵值對
    void putAll(Map<? extends K,? extends V> m) 復制映射
    boolean containsKey(Object key) 判斷是否包含 key
    boolean containsValue(Object value) 判斷是否包含 value
    V get(Object key) 返回鍵對應值
    Set keySet() 返回鍵的集合
    Collection values() 返回值的集合
    V remove(Object key) 刪除 key 對應條目
    Set<Map.Entry<K,V>> entrySet() 返回鍵值對的集合

    使用 keySet() 抽取 key 序列,將 map 中的所有keys生成一個 Set。

    使用 values() 抽取 value 序列,將 map 中的所有 values 生成一個 Collection。

    為什么一個生成 Set,一個生成 Collection?那是因為,key 總是獨一無二的,value 允許重復。

List

  1. Collection 的子接口,通過索引訪問元素,存儲一組不唯一、有序的對象

  2. 公共方法

    方法 描述
    E get(int index) 返回指定位置元素
    E set(int index,E element) 替換指定位置,返回被取代元素
    int indexOf(Object o) 返回 o 首次出現序號,不存在返回 -1
    int lastIndexOf(Object o) 返回 o 最后出現序號
    void add(int index,E element) 指定位置插入
    boolean add(E element) 最后位置插入
    E remove(int index) 刪除並返回指定位置元素
    boolean addAll(Collection<? extends E> c) 列表最后添加 c 中所有元素
    boolean addAll(int index,Collection<? extends E> c) 指定位置添加 c 中所有元素
    ListIterator listIterator() 返回迭代器
    ListIterator listIterator(int index) 返回指定位置開始的迭代器

Set

  1. Collection 的子接口,不保存重復元素,存儲一組唯一、無序的對象
  2. 公共方法:繼承自 Collection,未聲明其他方法,不提供 get 方法獲取元素

實現類

List派生類

  1. ArrayList

    • 數組列表,自動擴容,增長長度為原來的 50%

    • 基於數組,隨機訪問、遍歷效率高,插入刪除效率低

    • 可插入 null

  2. LiinkedList

    • 鏈式數據結構

    • 基於雙向鏈表,插入刪除效率高,隨機訪問、查找效率低

    • 可插入 null

    • 常用方法

      方法 描述
      public void addFirst(E e) 插入開頭
      public void addLast(E e) 插入尾部
      public E getFirst() 返回第一元素
      public E getLast() 返回最后元素
      public E removeFirst() 刪除並返回第一元素
      public E removeLast() 刪除並返回最后元素

Map派生類

  1. HashMap

    • 查找元素的時間復雜度 O(1)
    • 允許 null 鍵和 null 值
    • 鍵必須唯一,值可以重復,無序
    • 上座率:元素個數達到容量與上座率乘積時,容量自動翻倍
  2. TreeMap

    • 基於二叉搜索樹,查找元素時間復雜度 O(logn)

    • 實現了 SortedMap 接口

    • 不允許 null 鍵(空指針異常),允許 null 值

    • 鍵必須唯一,值可以重復,按鍵值從大到小排列

    • 常用方法

      方法 描述
      public K firstKey() 返回最低鍵
      public K lastKey() 返回最高鍵
      public SortedMap<K,V> headMap(K toKey) 返回鍵值小於 toKey 那部分映射
      public SortedMap<K,V> tailMap(K toKey) 返回大於等於 toKey 那部分映射
      public K lowerKey(K key) 返回小於給定鍵的最大鍵
      public K floorKey(K key) 返回小於等於給定鍵的最大鍵
      public K higherKey(K key) 返回大於給定鍵的最小鍵
      public K ceilingKey(K key) 返回大於等於給定鍵的最小鍵

Set派生類

  1. HashSet

    • 內部封裝了一個 HashMap,HashSet 作為 map 的 key 而存在,value 則是一個類屬性

    • 允許 null 元素

    • 不能添加重復元素,方法添加重復對象時不改變集合返回 false

    • 無序,不按插入順序,也不按 HashCode 順序

    • 常用方法

      方法 描述
      public boolean add(E e) 添加對象,返回成功與否
      public void clear() 清空集合
      public boolean contains(Object o) 判斷是否包含 o 元素
      public int size() 返回集合容量
  2. TreeSet

    • 基於 TreeMap 的鍵實現,實現 了SortedSet 接口
    • 不允許插入 null 元素(空指針異常)
    • 按元素從小到大排序
    • 不能添加重復元素
    • 常用方法
    方法 描述
    public K first() 返回最低元素
    public K last() 返回最高元素
    public SortedSet headSet(E e) 返回小於 e 那部分映射
    public SortedSet tailSet(E e) 返回大於等於 e 那部分映射
    public E lower(E e) 返回小於 e 最大元素
    public E floor(E e) 返回小於等於 e 的最大元素
    public E higher(E e) 返回大於 e 的最小元素
    public E ceiling(E e) 返回大於等於 e 的最小元素
  3. LinkedHashset

    • 繼承自 HashMap,內部加入鏈表保存元素順序

    • 基於元素進入集合的順序或者被訪問的順序排序

傳統類

  1. HashTable

    • Dictionary 的子類,實現了 Map 接口
    • 不允許 null 鍵,不允許 null 值
    • 鍵必須唯一,值可以重復,無序
    • 線程安全,支持同步
  2. Vector

    • 線程安全,同步訪問
    • 繼承自 AbstractList
  3. Properties

    • 繼承自 HashTable,實現了 Map 接口

    • 表示一個持久的屬性集,屬性列表中每個鍵及其對應值都是一個字符串

    • 常用方法

      方法 描述
      String getProperty(String key) 返回指定鍵對應屬性
      Object setProperty(String key, String value) 調用 Hashtable 的 put 方法
      void list(PrintStream streamOut) 將屬性列表輸出到指定的輸出流
      void list(PrintWriter streamOut) 將屬性列表輸出到指定的輸出流
      void load(InputStream streamIn) throws IOException 從輸入流中讀取屬性列表
      //加載 properties 配置文件的兩種方法,JDBCUtils 為例
      //方法一
      URL res = JDBCUtils.class.getClassLoader().getResource("jdbc.properties");
      String path = res.getPath();
      pro.load(new FileReader(URLDecoder.decode(path, "utf-8")));
      //方法二
      // InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
      InputStream is = JDBCUtils.class.getResourceAsStream("/jdbc.properties");
      pro.load(is);
      
  4. Stack

    • 繼承自 Vector ,先進后出

    • 線程安全

    • 常用方法

      方法 描述
      boolean empty() 判斷是否棧空
      Object peek() 查看棧頂元素,不刪除
      Object pop() 刪除棧頂元素,並返回
      Object push(Object element) 元素壓棧
      int search(Object element) 返回位置,以 1 為基數
  5. Dictionary

    • 抽象類,用來存儲鍵/值對,作用和Map類相似
  6. BitSet

    • 位集合, 按需增長的位向量

    • 使用場景:整數,無重復

    • 每一位的值都是一個 boolean 值 ,占用一 bit(不是一字節)

    • 內部基於 long 數組, 所以 BitSet 的大小為 long 類型大小(64位)的整數倍

    • 常用方法

      方法 描述
      void set(int index) 將指定索引處的位設置為 true
      void set(int index, boolean v) 將指定索引處的位設置為指定值
      void set(int startIndex, int endIndex) 將范圍內的位設置為 true(左開右閉)
      void set(int startIndex, int endIndex, boolean v) 將范圍內的位設置為指定值(左開右閉)
      boolean get(int index) 返回指定索引處的位值

算法

Collections

方法 描述
Collections.reverse(List l) 反轉
Collections.shuffle(List l) 混淆
Collections.sort(List l) 排序
Collections.swap(List l,int index1,int index2) 替換下標位置元素
Collections.rotate(List l,int step) 向右滾動 ,尾部移動到開頭
Collections.synchronizedList() 線程安全化
Collections.fill(List l,Object o) 填充
Collections.copy(List m,List n) n 中的元素復制到 m 中,並覆蓋相應索引的元素

迭代器

  1. Collection 定義了 toArray()、iterator()、size()方法,但並非所有實現類都重寫了這些方法,Set 不提供 get 方法,不能使用 size() 方式遍歷。

    //Set 遍歷方式
    Set<String> set = new HashSet<String>();
    //迭代器遍歷
    Iterator<String> it = set.iterator();
    while (it.hasNext()) 
    {
      String str = it.next();
      System.out.println(str);
    }
    
    //for循環遍歷:
    for (String str : set) 
          System.out.println(str);
    
    
  2. Iterator 接口常用方法

    方法 描述
    public abstract boolean hasNext() 判斷是否還有后續元素
    public abstract E next() 返回后續元素
    public abstract void remove() 刪除當前指向元素
  3. ListIterator 接口常用方法

    方法 描述
    public abstract boolean hashPrevious() 判斷是否有前驅元素
    public abstract E previous() 返回前驅元素
    public abstract add(E e) 插入 next() 返回值之前,previoous() 之后
    public abstract set(E e) 替換當前指向元素
    public abstract int nextIndex() 返回基於 next() 元素序號
    public abstract int previousIndex() 返回基於 previous() 元素序號

比較器

  1. Comparator類:一個類有多個屬性,不知道按哪個屬性進行排序時,通過 Comparator 類重寫 compare(Object o1,Object o2 )指定比較算法,再利用 Collections.sort(List l,Comparator c) 進行排序
  2. Comparable接口:實現接口,重寫 compareTO(Object another) 方法,利用 Collections.sort(List l)排序

Arrays

  1. 數組復制

    1. public static <T,U> T[] copyOfRange(U[] original, int from, int to)
      

      original:原數組 from:原數組的起始位置 to:終點位置(不包括)

    2. public static <T> T[] copyOf(T[] original, int newLength)
      

      original:原數組 newLength:要復制的長度

      StringBuider 中底層數組的擴容使用了 copyOf()

      copyOf() 內部是通過 System.arraycopy() 實現的

    3. System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
      

      src:原數組 srcPos:原數組起始位置

      dest:目標數組 destPost:目標數組的起始位置 length:復制長度

      List 中的 remove 方法使用了 arraycopy()

  2. 其他方法

方法 描述
public static String toString() 轉換為字符串
public static void sort() 排序
public static int binarySearch(Object[] a, Object key ) 搜索
public static boolean equals(long[] a, long[] b) 判斷是否相同
public static void fill(int[] a, int val)) 填充

HashCode

哈希集合查找元素為時間復雜度為 O(1) 的原理

  1. 獲得散列值:

    通過特定的哈希函數,每個對象都有對應的哈希值、

  2. hashcode對應到內存地址:

    可以使用一個數組 array,將要存的數據放在 array[hashcode] 位置上

  3. 哈希碰撞

    通過哈希方法,兩個不同的元素,獲得了相同的哈希值

    最常用用的解決辦法是拉鏈法,在同一地址上建立鏈表來存儲多個 hashcode 相同的元素

  4. 查找

    通過哈希值找到地址,若地址上有多個元素,則用 equals 判斷存儲位置是否相同

    對於哈希集合來說,如果重寫了元素對應的 equals() 方法或 hashcode()方法中的一個,也必須重寫另一個


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM