Collection集合
阿新 • • 發佈:2020-07-23
1 集合概述:
1.1 什麼是集合?有什麼用?
陣列其實就是一個集合。集合實際上就是一個容器。可以來容納其它型別的資料。
集合為什麼說在開發中使用較多?
集合是一個容器,是一個載體,可以一次容納多個物件。
在實際開發中,假設連線資料庫,資料庫當中有10條記錄。那麼假設把這10條記錄查詢出來,在java程式中會講10條資料封裝成10個java物件,
然後將10個java物件放到某一個集合當中,將集合傳到前端,然後遍歷集合,將一個數據一個數據展現出來。
1.2 集合不能直接儲存基本資料型別,另外集合也不能直接儲存Java物件。
集合當中儲存的都是java物件的記憶體地址。(或者說集合中儲存的是引用。)
list.add(100); // 自動裝箱 Integer
注意:
集合在java中本身是一個容器,是一個物件。
集合中任何時候儲存的都是“引用”
1.3 在java中每一個不同的集合,底層會對應不同的資料結構。往不同的集合中儲存元素,等於將資料放到了不同的資料結構當中,
什麼是資料結構?資料儲存的結構就是資料結構。不同的資料結構,資料儲存方式不同。例如:
陣列、二叉樹、連結串列、雜湊表...
以上這些都是常見的資料機構。
你往集合c1中放資料,可能是放到了陣列上了。
你往集合c2中放資料,可能是放到了二叉樹上了。
......
你使用不同的集合等同於使用了不同的資料結構。
你在java集合這一章節,你需要掌握的不是精通資料結構。java中已經將資料結構實現了,已經寫好了這些常用的集合類,你只需要掌握怎麼用?在什麼情況下
選擇哪一種合適的集合去使用即可。
new ArrayList(); 建立一個集合,底層是陣列。
new LinkedList(); 建立一個集合物件,底層是連結串列。
new TreeSet(); 建立一個集合物件,底層是二叉樹。
...
1.4集合在java JDK中哪個包下?
java.util.*;
所有的集合類和集合介面都在和hava.util包下。
1.5 為了讓大家掌握集合這塊的內容,最好能將集合的繼承結構圖背會!!!
集合整個這個體系是怎麼樣的一個機構,你需要有印象。
1.6 在java中集合分為兩大類:
一類是單個方式儲存元素:
單個方式儲存元素,這一類集合中的超級父介面:java.util.Collection;
一類是以鍵值對的方式儲存元素
以鍵值對的方式儲存元素,這一類集合中超級父類介面:java.util.Map;
2 總結重點:
第一個重點:把集合繼承結構圖 背會。
第二個重點:把Collection介面中常用方法測試幾遍。
第三個重點:把迭代器弄明白。
第四個重點:Collection介面中的remove方法和contains方法底層都會呼叫equals,把這個弄明白。
集合中儲存的是物件的記憶體地址:
Iterator迭代器原理:(注意:集合物件中儲存的是記憶體地址哦,不是直接儲存的物件或者基本資料型別哦。)
迭代原理:
Collection介面中常用的方法:
package com.javase.Collection; import java.util.ArrayList; import java.util.Collection; /* 關於java.util.Collection介面中常用的方法。 1 Collection中能存放什麼元素? 沒有使用“泛型”之前,Collection中可以儲存Object的所有子型別。 使用了“泛型”之後,Collection中只能儲存某個具體的型別。 集合後期我們會學習“泛型”語法。目前先不用管。Collection中什麼都可以存, 只要是Object的子型別就行。(集合中不能直接儲存基本資料型別,也不能存java物件,只是儲存java物件的記憶體地址。) 2 Collection中的常用方法: boolean add(Object e) 向集合中新增元素 int size() 獲取集合中元素的個數。 void clear() 清空集合 boolean contains(Object o) 判斷當前集合中是否包含元素o,包含返回true 不包含返回false boolean remove(Object o) 刪除集合中的某個元素 boolean isEmpty() 判斷該集合中元素的個數是否為0 Object[] toArray() 呼叫這個方法可以吧集合轉換成陣列。(作為了解,使用不多。)*/ public class CollectionTest01 { public static void main(String[] args) { // 建立一個集合物件 // Collection c = new Collection(); // 介面是抽象的,無法例項化。 // 多型 Collection c = new ArrayList(); // 測試Collection介面中常用的方法 c.add(1200);// 自動裝箱(java5的新特性),實際上是放進去了一個物件的記憶體地址。Integer x = new Integer(1200);c.add(3.14);// 自動裝箱 c.add(new Object()); c.add(true);// 自動裝箱 // 獲取集合中元素的個數 System.out.println("集合中元素的個數是:" + c.size()); // 4 // 清空集合中的元素 c.clear(); System.out.println("集合中元素的個數是:" + c.size()); // 0 // 在向集合中新增元素 c.add("hello");//"hello"物件的記憶體地址放到了集合當中。 c.add("world"); c.add("浩克"); c.add("綠巨人"); c.add("1"); // 判斷集合中是否包含"綠巨人" boolean flag = c.contains("綠巨人"); System.out.println(flag); // true boolean flag2 = c.contains("綠巨人2"); System.out.println(flag2); // false // 獲取集合中元素的個數 System.out.println("集合中元素的個數是:" + c.size()); // 5 // 刪除集合中某個元素 c.remove("1"); // 獲取集合中元素的個數 System.out.println("集合中元素的個數是:" + c.size()); // 4 // 判斷集合是否為空(集合中是否存在元素) System.out.println(c.isEmpty()); // false // 清空 c.clear(); System.out.println(c.isEmpty()); // true c.add(100); c.add("abc"); c.add('中'); c.add(true); c.add(new Student()); // 轉換成陣列(使用不多,瞭解一下。) Object[] o = c.toArray(); for (int i = 0; i < o.length; i++) { System.out.print(o[i] + " "); } } } class Student{ public String toString() { return "這是一個Student類"; } }
關於集合遍歷/迭代專題(重點*****)
package com.javase.Collection; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /* 關於集合遍歷/迭代專題(重點 *****) */ public class CollectionTest02 { public static void main(String[] args) { // 注意:以下講解的遍歷方式/迭代方式,是所有Collection通用的一種方式。 // 在Map集合中不能用。在所有Collection以及子類中使用。 // 建立集合物件 Collection c = new ArrayList(); // 後面的集合無所謂,主要是看前面的Collection介面,怎麼遍歷/迭代 // 新增元素 c.add("abc"); c.add(123); c.add(true); c.add(new Object()); c.add('中'); // 對集合Collection進行遍歷/迭代 // 第一步:獲取集合物件的迭代器物件Iterator Iterator it = c.iterator(); // 第二步:通過以上獲取的迭代器物件開始迭代/遍歷集合 // Iterator迭代器中的方法 /* boolean hasNext() 如果仍有元素可以迭代,則返回 true。 Object next() 返回迭代的下一個元素。 */ // boolean hasNext = it.hasNext(); while (it.hasNext()){ // 不管你當初放進去什麼,取出來統一都是Object。 Object obj = it.next(); System.out.println(obj); } } }
迭代案例2:
package com.javase.Collection; import java.util.*; public class CollectionTest03 { public static void main(String[] args) { // 建立集合物件 Collection c1 = new ArrayList(); // ArrayList集合:有序可重複。 // 新增元素 c1.add(1); c1.add(2); c1.add(3); c1.add(4); c1.add(1); // 迭代集合 Iterator t1 = c1.iterator(); while (t1.hasNext()){ // 存進去是什麼型別,取出來還是什麼型別。 Object o = t1.next(); /*if(o instanceof Integer){ System.out.println("Integer型別"); }*/ // 只不過在輸出的時候會轉換成字串。因為這裡println()會呼叫toString()方法。 System.out.println(o); } // 建立HashSet集合物件: 無序不可重複 Collection c2 = new HashSet(); // 無序:存進去和取出的順序不一定不同。 // 不可重複: 已經儲存了100了 不能在儲存100了。 c2.add(100); c2.add(200); c2.add(300); c2.add(400); c2.add(500); c2.add(600); c2.add(700); c2.add(800); c2.add(900); c2.add(100); // 迭代集合 Iterator t2 = c2.iterator(); while (t2.hasNext()){ System.out.println(t2.next()); } } }
Collection中的contains()方法底層原理:
深入Collection集合的contains方法:
package com.javase.Collection; import java.util.ArrayList; import java.util.Collection; /* 深入Collection集合的contains方法: boolean contains(Object o) 判斷集合中是否包含某個物件o 如果包含返回true 如果不包含返回false contains 方法是用來判斷集合中是否包含某個元素的方法, 那麼他在底層是怎麼判斷集合中是否包含某個元素的呢? 呼叫了equals方法進行比對。 equals方法返回true,就表示包含這個元素。 */ public class CollectionTest04 { public static void main(String[] args) { // 建立集合 Collection c = new ArrayList(); // 新增元素 String s1 = new String("abc"); // 0x1111 c.add(s1);// 放進去了一個"abc" String s2 = new String("def"); // 0x2222 c.add(s2); // 集合中的元素個數 System.out.println(c.size()); // 新建的物件String String x = new String("abc"); // 0x2222 // c集合中是否包含x?結果猜測一下是true還是false? System.out.println(c.contains(x));// 判斷集合中是否存在"abc" true } }
測試contains方法和remove方法案例:
package com.javase.Collection; import java.util.ArrayList; import java.util.Collection; /* 測試contains方法 測試remove方法。 結論:存放在一個集合中的型別,一定要重寫equals方法。 */ public class CollectionTest05 { public static void main(String[] args) { // 建立集合物件 Collection c = new ArrayList(); // 建立User物件 User u1 = new User("jack"); User u2 = new User("jack"); // 將物件加到集合中 c.add(u1); //判斷集合中是否包含u2 // 沒有重寫equals方法之前 // System.out.println(c.contains(u2)); // false // 重寫equals方法之後,比較的時候會比較name。 System.out.println(c.contains(u2));//true c.remove(u2); System.out.println(c.size());//0 /*Integer x = new Integer(10000); c.add(x); Integer y = new Integer(10000); System.out.println(c.contains(y));//true*/ // Integer 類的 equals方法重寫了。 // x.equals(y) --> true // 建立集合物件 Collection c1 = new ArrayList(); // 建立字串物件 String s1 = new String("hello"); // 加進去 c1.add(s1); // 建立字串物件 String s2 = new String("hello"); // 刪除s2 c1.remove(s2); // 集合中元素的個數是? System.out.println(c1.size());// 0 } } class User{ private String name; public User() { } public User(String name) { this.name = name; } // 重寫equals方法 // 將來呼叫equals方法的時候,一定是呼叫這個重寫的equals方法。 // 這個equals方法的比較原理是:只要姓名一樣就表示同一個使用者。 public boolean equals(Object o) { if(o == null || !(o instanceof User)) return false; if(o == this) return true; User u = (User)o; //如果名字一樣表示同一個人。(不再比較物件的記憶體地址了。比較內容) return u.name.equals(this.name); } }
關於集合元素的remove:
package com.javase.Collection; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /* 關於集合元素的remove 重點:當集合的結構發生改變時,迭代器必須重新獲取,如果還是用以前老的迭代器,會出現異常:java.util.ConcurrentModificationException 重點:在迭代器集合元素的過程中,不能呼叫集合物件的remove方法,刪除元素: c.remove(0);迭代過程中不能這樣。 會出現:java.util.ConcurrentModificationException異常。 重點:在迭代元素過程當中,一定要使用迭代器Iterator的remove方法,刪除元素。不要使用集合自帶的remove方法刪除元素。 */ public class CollectionTest06 { public static void main(String[] args) { // 建立集合 Collection collection = new ArrayList(); // 注意:此時獲取的迭代器,指向的是那時集合中沒有元素狀態下的迭代器。 // 一定要注意:集合結構只要發生改變,迭代器必須重新獲取。 // 當集合結構發生了改變,迭代器沒有重新獲取時,呼叫next()方法時:java.util.ConcurrentModificationException // Iterator iterator = collection.iterator(); // 新增元素 collection.add(1); collection.add(2); collection.add(3); // 獲取迭代器 Iterator iterator = collection.iterator(); while (iterator.hasNext()){ // 編寫程式碼時next()返回值型別必須是Object // Integer i = iterator.next(); Object obj = iterator.next(); System.out.println(obj); } Collection c1 = new ArrayList(); c1.add("abc"); c1.add("def"); c1.add("xyz"); Iterator it1 = c1.iterator(); while (it1.hasNext()){ Object o = it1.next(); // 刪除元素 // 刪除元素之後,集合的結構發生了變化,應該重新去獲取迭代器。 // 但是,迴圈下一次的時候並沒有重新獲取迭代器,所以會出現異常。 // 出異常根本原因:集合中元素刪除了,但是沒有更新迭代器(迭代器不知道集合變化了。) // c1.remove(o);//直接通過集合去刪除元素,沒有通知迭代器,(導致迭代器的快照和原集合狀態不同。) // System.out.println(o); // 使用迭代器來刪除可以嗎? // 迭代器去刪除時,會自動更新迭代器,並且更新集合(刪除集合中的元素)。 it1.remove();// 刪除的一定是迭代器指向的當前元素。 System.out.println(o); } System.out.println(c1.size()); } }