Java 集合學習--集合概述
一、集合框架
集合,通常也叫容器,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 集合學習--集合概述