Java集合類的概述

前述

  複習一下Java中的集合類,是面試筆試中常考察的一個點,特意作的整理。java

什麼是集合類?

  集合類,也叫容器類。Java集合類能夠用來存儲數量龐大的對象。python

  咱們和數組進行對比:面試

  數組:存儲基本數據類型,數據類型單一,長度固定,不能動態添加數據。算法

  集合:存儲的便可是基本類型的值,也能夠是對象,能夠存儲多種數據類型,長度可變,能夠動態添加數據。編程

 

Java集合類的體系

  Java集合類主要有兩個接口派生而出:Collection和Map。即集合類都是實現的這兩個接口。咱們在實際編程中常用的有 List、Set、Queue(這些是實現的 Collection 接口)HashMap、TreeMap、HashTable(這些實現的 Map 接口)數組

Collection接口結構

  Collection 接口位於 Java.util 包下,是一個父接口, List、Set、Queue 都是實現的 Collection 接口。Collection 作爲父接口提供一些操做集合類的方法,所以它的子接口也有這些方法。安全

  Collection 接口不能被實例化,而且在實際的編程過程當中幾乎不會使用它進行數據的存儲。數據結構

Map接口結構

  Map 接口實現的是鍵值對的存儲,相似 python 中的 dict。框架

  Map中比較常見的是 HashMap、TreeMap、Hashtable 類。ide

 

Set接口

  Set 接口繼承自 Collection 接口,Collection 接口有的方法 Set 接口中也有。

  Set 接口自身的特性:

    • 不容許重複元素
    • 不區分前後順序(無序)
    • 容許值是 null

  Set 接口有兩個比較經常使用的具體實現,HashSet、TreeSet。下面分別說一下這兩個集合類。

HashSet

  主要特色是快速查找元素。HashSet 是基於 Hash 算法來實現的,在每次添加新的對象的時候,會根據散列碼來判斷對象是否重複,散列碼的獲取是經過 Object 的 hashCode() 來實現的。一樣 HashSet 也是無序的。

 1 import java.util.*;
 2 /**
 3  * @author jyroy
 4  * HashSet使用
 5  */
 6 public class HashSetDemo {
 7     public static void main(String[] args) {
 8         HashSet hashSet = new HashSet();
 9         hashSet.add("Tom");
10         hashSet.add("Jack");
11         hashSet.add("Roy");
12         System.out.println(hashSet);
13     }
14 }

  當有重複元素添加時,結果以下

 1 import java.util.*;
 2 /**
 3  * @author jyroy
 4  * HashSet使用
 5  */
 6 public class HashSetDemo {
 7     public static void main(String[] args) {
 8         HashSet hashSet = new HashSet();
 9         hashSet.add("Tom");
10         hashSet.add("Tom");
11         hashSet.add("Jack");
12         hashSet.add("Roy");
13         System.out.println(hashSet);
14     }
15 }

 

TreeSet

  主要特色是會進行天然排序,一樣不能重複。參考以下的代碼,能夠看出 TreeSet 把本來無序的值進行了從新排序,依據的就是天然排序。

 1 import java.util.*;
 2 public class TreeSetDemo {
 3     public static void main(String[] args) {
 4         TreeSet treeSet = new TreeSet();
 5         treeSet.add("Tom");
 6         treeSet.add("Jack");
 7         treeSet.add("Roy");
 8         System.out.println(treeSet);
 9     }
10 }

 

  然而,在實際開發中不少時候咱們不少時候遵循的不是天然排序,而是有本身定義的排序規則,咱們要作的就是新建一個類而且實現 compareTo() 方法。

  下面的代碼實現的是根據年齡由小到大進行排序,比較簡單,一看就懂的代碼。

 1 import java.util.TreeSet;
 2 class Person implements Comparable{
 3     public String name;
 4     public int age;
 5     @Override
 6     public String toString() {
 7         return "Person [name=" + name + ", age=" + age + "]";
 8     }
 9     @Override
10     public int compareTo(Object o) {
11         Person person = (Person) o;
12         if(this.age < person.age) {
13             return -1;
14         }else if(this.age > person.age) {
15             return 1;
16         }else {
17             return 0;
18         }
19     }
20 }
21 public class TreeSetDemoCompareto {
22     public static void main(String[] args) {
23         TreeSet treeSet = new TreeSet();
24         Person person1 = new Person();
25         Person person2 = new Person();
26         Person person3 = new Person();
27         person1.name = "Tom";
28         person1.age = 20;
29         person2.name = "Jack";
30         person2.age = 21;
31         person3.name = "Roy";
32         person3.age = 22;
33         treeSet.add(person1);
34         treeSet.add(person2);
35         treeSet.add(person3);
36         System.out.println(treeSet);
37     }
38 }

 

List接口

  List 接口繼承了 Collection 接口,Collection 接口有的方法 List 中也有。

  List 接口自身的特性:

    • 利用數組方式提供了獲取、修改、刪除的功能。
    • 能夠經過方法來獲取元素的位置。
    • 容許重複元素的有序集合。

  List 接口有兩個比較經常使用的具體實現,ArrayList、Vector、LinkedList。下面分別說一下這兩個集合類。

ArrayList

  ArrayList 自己是經過數組的方式實現的,大小能夠隨着對象的增長而增長。查詢效率比較高,增長、刪除的效率比較低,這也是數組的一種特性。非線程安全的。並且是有序的。

 1 import java.util.*;
 2 /**
 3  * @author jyroy
 4  */
 5 public class ArrayListDemo {
 6     public static void main(String[] args) {
 7         List arrayList = new ArrayList();
 8         arrayList.add("Tom");
 9         arrayList.add("Jack");
10         arrayList.add("Roy");
11         System.out.println(arrayList);
12     }
13 }

 

Vector

  Vector 和 ArrayList 是類似的,都是經過數組來實現的。

  最大的區別就是線程安全方面。Vector 是線程安全的,同步的,Vector類對集合的元素操做時都加了synchronized,保證線程安全。而 ArrayList 是非線程安全的。也是由於線程安全的問題,ArrayList 的查詢效率比 Vector 要高。

  另一個區別是在擴容方面,Vector默認擴容是增加一倍的容量,Arraylist是增加50%+1的容量。

  Vector與ArrayList的remove,add(index,obj)方法都會致使內部數組進行數據拷貝的操做,這樣在大數據量時,可能會影響效率。

 1 import java.util.*;
 2 public class VectorDemo {
 3     public static void main(String[] args) {
 4         List vectorList = new Vector();
 5         vectorList.add("Roy");
 6         vectorList.add("Tom");
 7         vectorList.add("Jack");
 8         System.out.println(vectorList);
 9     }
10 }

 

LinkedList

  LinkedList 和 ArrayList、Vector相比,在方法的使用上都是類似的。

  LinkedList 是基於雙向鏈表的,比較利於對象的增長和刪除操做,可是對查詢的支持不夠好,這是鏈表的特色。 LinkedList 一樣是線程不安全的。

 1 import java.util.*;
 2 public class LinkedListDemo {
 3     public static void main(String[] args) {
 4         List linkedList = new LinkedList();
 5         linkedList.add("Roy");
 6         linkedList.add("Jack");
 7         linkedList.remove(0);
 8         linkedList.add("Tom");
 9         System.out.println(linkedList);
10     }
11 }

 

Queue接口

  Queue 是 Collection 的子接口,中文稱爲隊列,特性就是先進先出,先進入隊列的對象,在進行刪除的時候最早被刪除。全部的刪除操做都是在隊首進行的,全部的插入操做都是在隊尾進行的。

 1 import java.util.*;
 2 public class QueueDemo {
 3     public static void main(String[] args) {
 4         Queue queue = new LinkedList();
 5         queue.add("Tom");
 6         queue.add("Roy");
 7         System.out.println(queue.poll());  //出隊列操做
 8         queue.add("Jack");
 9         System.out.println(queue);
10     }
11 }

 

HashMap

  HashMap 是基於散列表的 Map 接口的實現類,線程不安全。

  散列表是經過關鍵碼值(Key value)而直接進行訪問的數據結構。它經過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。

  下面的代碼實現了獲取key爲 2 的元素的 value。

 1 import java.util.*;
 2 public class HashMapDemo {
 3     public static void main(String[] args) {
 4         HashMap hashMap = new HashMap();
 5         hashMap.put(1, "Tom");
 6         hashMap.put(2, "Jack");
 7         hashMap.put(3, "Roy");
 8         System.out.println(hashMap.get(2));
 9         System.out.println(hashMap);
10     }
11 }

 

TreeMap

  TreeMap 是根據紅黑樹算法實現的,TreeMap最大的特性就是支持天然排序。從下面的代碼中也能夠很是清晰的看出 TreeMap 利用 key 值進行了天然排序。

  紅黑樹(Red Black Tree) 是一種自平衡二叉查找樹,是在計算機科學中用到的一種數據結構,典型的用途是實現關聯數組。

 1 import java.util.*;
 2 public class TreeMapDemo {
 3     public static void main(String[] args) {
 4         TreeMap treeMap = new TreeMap();
 5         treeMap.put("2", "Tom");
 6         treeMap.put("1", "Roy");
 7         treeMap.put("3", "Jack");
 8         System.out.println(treeMap);
 9     }
10 }

HashTable

  HashTable 和 HashMap 是基本一致的。

  最大的區別是 HashTable 是線程安全的,HashMap 不是。

 1 import java.util.*;
 2 public class HashTableDemo {
 3     public static void main(String[] args) {
 4         Hashtable hashtable = new Hashtable();
 5         hashtable.put("2", "Tom");
 6         hashtable.put("1", "Roy");
 7         hashtable.put("3", "Jack");
 8         System.out.println(hashtable);
 9     }
10 }

 

 

常見問題

  這些問題是在其餘一些大佬的博客中看到,作了一個整理,都是 Java 集合類的問題。

  1. ArrayList和LinkedList的特色和區別?

  ArrayList: 底層用數組實現,因爲數組能夠經過下標直接訪問指定索引的元素,所以,ArrayList經過索引查詢元素很是快。但因爲插入和刪除元素時都會進行數組的從新排列,所以,ArrayList的插入和刪除操做比較慢。

  LinkedList:底層用鏈表實現,因爲鏈表沒有具體的下標,所以,訪問某個索引的節點時須要遍歷該節點前面的全部元素,速度比較慢。因爲插入和刪除元素時只須要更新相應元素的指針(或引用),不用從新排列元素,所以,LinkedList對插入和刪除操做比較快。

  LinkedList 比 ArrayList消耗更多的內存,由於 LinkedList 中的每一個節點存儲了先後節點的引用。


  
2. ArrayList和Vector的區別?  

  ArrayList非線程安全,Vector線程安全。在擴容時,ArrayList默認擴容當前容量的50%,但Vector默認擴容當前容量的100%。

 

  3. HashSet和TreeSet的區別? 

  HashSet基於HashMap,用鍵來存放HashSet的值,因爲HashMap的鍵不能重複,所以,HashSet的值也不會重複,這是集合的一個特色。
  TreeSet基於TreeMap,也是用鍵來存放TreeSet的值。TreeMap的底層實現是紅黑樹,其根據鍵排序,能夠獲得排好序的數據。

  4. HashMap和HashTable的區別?

  HashMap非線程安全,HashTable線程安全。
  HashMap能夠容許一個null鍵和多個null值,但HashTable不容許,會出現NullPointerException。

 

  5. HashMap和TreeMap的區別?

  HashMap中存放的鍵是隨機的,具備較快的訪問和存取速度,TreeMap中的鍵是按照天然排序排好的。

 

  6. Java集合框架的基礎接口有哪些?

  Collection 和 Map ,一個元素集合,一個是鍵值對集合; 其中 List、Set、Queue 接口繼承了 Collection 接口,一個是有序元素集合,一個是無序元素集合,一個是隊列; 而 ArrayList 和 LinkedList 實現了 List 接口,HashSet 實現了 Set 接口,這幾個都比較經常使用; HashMap、HashTable、TreeMap 實現了 Map 接口,而且 HashTable 是線程安全的,HashMap 是非線程安全的,可是 HashMap 性能更好。

  

  7. 如何決定選用HashMap仍是TreeMap?

   對於在Map中插入、刪除和定位元素這類操做,HashMap是最好的選擇。然而,假如你須要對一個有序的key集合進行遍歷,TreeMap是更好的選擇。

  

  8. 哪些集合類提供對元素的隨機訪問?

  ArrayList、HashMap、TreeMap和HashTable類提供對元素的隨機訪問。

 

  9. Array和ArrayList有何區別?何時更適合用Array?

  Array能夠容納基本類型和對象,而ArrayList只能容納對象。

  Array是指定大小的,而ArrayList大小是根據內容自動擴張的。

  Array沒有提供ArrayList那麼多功能,好比addAll、removeAll和iterator等。儘管ArrayList明顯是更好的選擇,但也有些時候Array比較好用。

  (1)若是列表的大小已經指定,大部分狀況下是存儲和遍歷它們。

  (2)對於遍歷基本數據類型,儘管Collections使用自動裝箱來減輕編碼任務,在指定大小的基本類型的列表上工做也會變得很慢。

  (3)若是你要使用多維數組,使用[][]比List<List<>>更容易。

相關文章
相關標籤/搜索