1. 程式人生 > >Java 集合學習--集合概述

Java 集合學習--集合概述

err null 鏈表 算法 哈希 學習 sta new t 基本

一、集合框架  

集合,通常也叫容器,java中有多種方式保存對象,集合是java保存對象(對象的引用)的方式之一,之前學習的數組是保存對象的最有效的方式,但是數組卻存在一個缺陷,數組的大小是固定的,但是往往我們在寫程序的時候,並不知道需要保存多少個對象,或者是否需要用更復雜的方式來存儲對象。而java提供集合類來解決這個問題。java中集合大家族的成員實在是太豐富了,有常用的ArrayList、HashMap、HashSet,也有不常用的Stack、Queue,有線程安全的Vector、HashTable,也有線程不安全的LinkedList、TreeMap等等!下圖非常明了的展示了整個集合家族的關系。(圖片來自網絡)

技術分享圖片

從上圖中可以看出,集合類主要分為兩大類:Collection和Map。

List接口通常表示一個列表(數組、隊列、鏈表、棧等),其中的元素可以重復,常用實現類為ArrayList和LinkedList,另外還有不常用的Vector。另外,LinkedList還是實現了Queue接口,因此也可以作為隊列使用。

Set接口通常表示一個集合,其中的元素不允許重復(通過hashcode和equals函數保證),常用實現類有HashSet和TreeSet,HashSet是通過Map中的HashMap實現的,而TreeSet是通過Map中的TreeMap實現的。另外,TreeSet還實現了SortedSet接口,因此是有序的集合(集合中的元素要實現Comparable接口,並覆寫Compartor函數才行)。

Map是一個映射接口,其中的每個元素都是一個key-value鍵值對,同樣抽象類AbstractMap通過適配器模式實現了Map接口中的大部分函數,TreeMap、HashMap、WeakHashMap等實現類都通過繼承AbstractMap來實現,另外,不常用的HashTable直接實現了Map接口,它和Vector都是JDK1.0就引入的集合類。

Iterator是遍歷集合的叠代器(不能遍歷Map,只用來遍歷Collection),Collection的實現類都實現了iterator()函數,它返回一個Iterator對象,用來遍歷集合,ListIterator則專門用來遍歷List。而Enumeration則是JDK1.0時引入的,作用與Iterator相同,但它的功能比Iterator要少,它只能再Hashtable、Vector和Stack中使用。

Arrays和Collections是用來操作數組、集合的兩個工具類,例如在ArrayList和Vector中大量調用了Arrays.Copyof()方法,而Collections中有很多靜態方法可以返回各集合類的synchronized版本,即線程安全的版本,當然了,如果要用線程安全的結合類,首選Concurrent並發包下的對應的集合類。

二、基本使用

1.List

List是一個有序,可以重復的集合,主要實現有下面三種:

①、List list1 = new ArrayList();

底層數據結構是數組,查詢快,增刪慢;線程不安全,效率高

②、List list2 = new Vector();

底層數據結構是數組,查詢快,增刪慢;線程安全,效率低,幾乎已經淘汰了這個集合

③、List list3 = new LinkedList();

底層數據結構是鏈表,查詢慢,增刪快;線程不安全,效率高。

具體的使用如下:

 1 public class ListDemo {
 2     
 3     public static void main(String[] args) {        
 4         ArrayList<Integer> list = new ArrayList<Integer>();
 5         //1.添加元素
 6         list.add(new Integer(10));
 7         list.add(1,20);//20自動轉型為包裝類
 8         list.addAll(list);
 9         System.out.println(list.toString());//通過叠代器遍歷集合,拼接字符串打印
10         //2.相關屬性
11         System.out.println("list大小:"+list.size());
12         System.out.println("是否為空:"+list.isEmpty());
13         //3.刪除元素
14         list.remove(0);//通過索引刪除元素
15         System.out.println(list);
16         //4.查找元素
17         System.out.println(list.get(0));
18         //叠代集合
19         Iterator<Integer> iterator = list.iterator();
20         while(iterator.hasNext()){
21             System.out.print(iterator.next()+"\t");
22         }
23         System.out.println("\n------------------------");
24         LinkedList<String> list2 = new LinkedList<String>();
25         list2.add("a");
26         list2.add(1,"b");
27         list2.addAll(list2);
28         System.out.println(list2);
29         System.out.println("list大小:"+list2.size());
30         System.out.println("是否為空:"+list2.isEmpty());
31         list2.remove("a");
32         System.out.println(list2);
33         System.out.println("最後一個元素是:"+list2.getLast());
34         Iterator<String> iterator2 = list2.iterator();
35         while(iterator2.hasNext()){
36             System.out.print(iterator2.next()+"\t");
37         }
38     }
39 }

結果輸出:

[10, 20, 10, 20]
list大小:4
是否為空:false
[20, 10, 20]
20
20    10    20    
------------------------
[a, b, a, b]
list大小:4
是否為空:false
[b, a, b]
最後一個元素是:b
b    a    b

2.Set

set是一個無序,不可重復的集合。主要實現有三種:

①、Set set1 = new HashSet();

底層結構是通過HashMap實現,在jdk1.8後HashMap的底層實現主要是借助數組、鏈表以及紅黑樹。HashSet的特點是不保證元素的插入順序,不可重復,非線程安全,允許集合元素為null.

②、Set set2 = new LinkedHashSet()

底層結構是通過LinkedHashMap實現,LinkedHashMap繼承HashMap,本質上也是是借助,數組,鏈表以及紅黑樹實現。特點是底層采用鏈表和哈希表的算法。鏈表保證元素的添加順序,哈希表保證元素的唯一性,非線程安全

③、Set set3 = new TreeSet()

底層結構是借助紅黑樹實現,特點是元素不可重復,不保證元素的添加順序,對集合中元素進行排序,非線程安全。

具體的使用如下:

 1 public class SetDemo {
 2     
 3     public static void main(String[] args) {
 4         //HashSet的使用
 5         HashSet<String> set1 = new HashSet<String>();
 6         //1.添加元素
 7         set1.add("1");
 8         set1.add("a");
 9         set1.add("c");
10         set1.add("b");
11         set1.addAll(set1);
12         System.out.println(set1);//通過遍歷輸出結合的元素,從結果可以看出,HashSet集合不允許元素重復,不保證插入的順序
13         //2.相關屬性或方法
14         System.out.println("是否包含c:"+set1.contains("c"));//是否包含某個元素
15         System.out.println("是否為空:"+set1.isEmpty());//是否為空
16         System.out.println("元素個數:"+set1.size());
17         //3.刪除某個元素
18         System.out.println(set1.remove("d"));//刪除某個元素是否成功
19     
20         //4.遍歷集合
21         Iterator<String> iterator = set1.iterator();
22         while(iterator.hasNext()){
23             if(iterator.next().equals("a")){
24                 iterator.remove();//借助叠代器刪除某個元素,推薦這種方法
25             }
26         }
27         System.out.println("刪除元素a後的set集合的元素個數:"+set1.size()+" "+set1);
28         for (String str : set1) {   //本質上是借助叠代器進行遍歷
29             System.out.print(str+"\t");
30         }
31         
32         System.out.println("\n----------------------");
33         //LinkedHashSet
34         LinkedHashSet<String> set2 = new LinkedHashSet<String>();
35         //1.添加元素
36         set2.add("1");
37         set2.add("a");
38         set2.add("c");
39         set2.add("b");
40         set2.addAll(set2);
41         System.out.println(set2);//保證元素的插入順序,不允許重復。
42         //其他的使用與HashSet類似,不過多重復
43         System.out.println("\n----------------------");
44         //
45         TreeSet<Integer> set3 = new TreeSet<Integer>(new Comparator<Integer>() {
46 
47             @Override
48             public int compare(Integer o1, Integer o2) {
49                 if(o1<o2){
50                     return 1;
51                 }else if(o1>o2){
52                     return -1;
53                 }else {
54                     return 0;
55                 }
56             }
57         });
58         set3.add(2);
59         set3.add(3);
60         set3.add(1);
61         System.out.println(set3);//集合中的元素默認按字典順序升序排序,通過紅黑樹實現,顯示的是[1,2,3],由於對比較方法進行重寫,是其倒序排序
62         //其他使用類似HashSet
63         
64     }
65 
66 }

結果輸出:

[1, a, b, c]
是否包含c:true
是否為空:false
元素個數:4
false
刪除元素a後的set集合的元素個數:3 [1, b, c]
1    b    c    
----------------------
[1, a, c, b]

----------------------
[3, 2, 1]

3.Map

①、Map map = new HashMap();

底層結構是數組,哈希表以及紅黑樹,特點是不保證映射關系添加的先後順序,key不允許重復,key判斷重復的標準是:key1和key2的equal為true,以及hashcode相等。

②、Map map = new LinkedHashMap();

底層結構是鏈表、哈希表以及紅黑樹,特點是Map中的key保證添加的先後順序,key不允許重復,key重復的判斷標準和HashMap一致。

③、Map map = new TreeMap();

底層結構是紅黑樹。特點是Map中的key保證先後添加的順序,不允許重復。key判斷的key的compare的結果

具體使用如下:

 1 public class MapDemo {
 2     
 3     public static void main(String[] args) {
 4         //HashMap
 5         HashMap<String, Integer> map1 = new HashMap<String, Integer>();
 6         //1.添加鍵值對
 7         map1.put("a", 1);
 8         map1.put("f", 2);
 9         map1.put("c", 3);
10         System.out.println(map1);
11         map1.put("a", 10);
12         System.out.println(map1);//key不允許重復,當重復的時候,後者覆蓋前者的值
13         //2.相關屬性和方法
14         System.out.println("鍵值對個數:"+map1.size());
15         System.out.println(map1.isEmpty());
16         System.out.println(map1.containsKey("g"));
17         System.out.println(map1.remove("a", 50));//刪除指定鍵值對
18         //3.通過key查找值,獲取key或value
19         System.out.println("f對應的值:"+map1.get("f"));
20         System.out.println(map1.keySet());//獲取所有的key,並且返回一個key的Set集合
21         System.out.println(map1.values());//返回所有的value
22         //4.hashmap的變量
23         //4.1二次取值遍歷
24         for(String key:map1.keySet()){
25             System.out.print(key+"="+map1.get(key)+" ");
26         }
27         System.out.println();
28         //4.2通過叠代器
29         Iterator<Entry<String, Integer>> iterator= map1.entrySet().iterator();
30         while(iterator.hasNext()){
31             Entry<String, Integer> entry= iterator.next();
32             System.out.print(entry.getKey()+"="+entry.getValue()+" ");
33         }
34         System.out.println();
35         //4.3推薦,尤其是容量大時  通過Map.entrySet遍歷key和value,與4.2本質上一樣
36         for(Entry<String, Integer> entry: map1.entrySet()){
37             System.out.print(entry.getKey()+"="+entry.getValue()+" ");
38         }
39         System.out.println("\n---------------------");
40         
41         
42         LinkedHashMap<String, Integer> map2 = new LinkedHashMap<String, Integer>();
43         map2.put("a", 1);
44         map2.put("f", 2);
45         map2.put("c", 3);
46         System.out.println(map2);//保證鍵值對的插入順序
47         //LinkedHashMap繼承HashMap其他使用類似HashMap
48         System.out.println("\n---------------------");
49         TreeMap<String, Integer> map3 = new TreeMap<String, Integer>();
50         map3.put("a", 1);
51         map3.put("f", 2);
52         map3.put("c", 3);
53         System.out.println(map3);//保證鍵值對的插入順序,key進行字典順序的升序排序
54         System.out.println(map3.firstKey());
55         System.out.println(map3.lastKey());//獲取最後一個key
56         //其他使用類似HashMap
57         
58         
59     }
60 
61 }

結果輸出:

{a=1, c=3, f=2}
{a=10, c=3, f=2}
鍵值對個數:3
false
false
false
f對應的值:2
[a, c, f]
[10, 3, 2]
a=10 c=3 f=2 
a=10 c=3 f=2 
a=10 c=3 f=2 
---------------------
{a=1, f=2, c=3}
---------------------
{a=1, c=3, f=2}
a
f

4.Map和Set集合的關系總結

  • HashSet借助HashMap實現,都采哈希表和紅黑樹算法; TreeSet借助TreeMap實現, 都采用 紅黑樹算法;LinkedHashMap 和 LinkedHashSet 都采用 哈希表算法和紅-黑樹算法。
  • Set集合實際上是由Map集合的key組成。

Java 集合學習--集合概述