集合: 1、作用: 保存多條數據。 嘮叨:同樣是保存數據,其保存的內容不限,長度不限。 2、集合間的相互關係: Collection--Set —HashSet --List—ArrayList —LinkedList Map—HashMap 集合在底層實現時:依然使用數組,但是性能優於數組。 一、
集合:
1、作用: 保存多條數據。
嘮叨:同樣是保存數據,其保存的內容不限,長度不限。
2、集合間的相互關係:
Collection--Set —HashSet
--List—ArrayList
—LinkedList
Map—HashMap
集合在底層實現時:依然使用數組,但是性能優於數組。
一、
1、List
1)list存儲不唯一,有序的數據。
2)ArrayList本質上是長度可變的數組,遍歷或者隨機訪問時效率更高。
LinkedList使用鏈式存儲,插入或者刪除時效率更高。
3)常用方法:
a) 添加add(Object obj)//順序添加
Add(int index,Object obj)//在指定位置添加
b) 修改set(int index,Object obj)//修改指定下標的值
c) 刪除remove(int index)//通過下標刪除
Remove(Object obj)//刪除指定數據
d) get(int index)//查看指定下標的值
e)獲取及和大小:size()
4)如果集合中存儲的數據是對象時,取出數據後,需要向下轉型
List list =new ArrayList();
List.add(new Son());
Son s = (Son)list.get();//取出對象後,強轉
2、LinkedList
1) 之前ArrayList擁有的方法,LinkedList同樣擁有
2) LinkedList獨有方法:
a). addFirst(Object obj);
b). addLast(Object obj);
c). removeFirst(Object obj);
d). removeLast(Object obj);
e). getFitst(Object obj);
f). getLast(Object obj);
註:如果調用上面方法,那麼new對象時,聲明使用LinkedList
示例:LinkedList list = new LinkedList();
主要是 實際工作中的差別,方法基本相同。
3、增強for迴圈
4、泛型
作用:限定集合或方法中添加的數據只能是限定的類型,以保證集合中數據的一致性
語法:<限定的數據類型>
示例:List<User> list = new ArrayList<User>();表明list中只能添加User類型的對象
註:添加泛型的集合,使用foreach遍歷時,可以直接使用泛型中的類型接收數據
示例:for(User u:list){}
當時出了這樣一個 bug:
public class ArrayList(){
public static void main(String[] args){
List myList = new ArrayList();
}
}
//然後就報錯了,這是因為,他會迴圈調用自身,我們起的名字跟人家用的名字重名了,重名其實不要緊,最重要的是,這樣就不認為ArrayList 是一個 List,需要讓我們的ArrayList 實現List介面。好吧,最好的辦法 還是把我們的名字改掉。
//我們的類不要叫做ArrayList。
相同的bug後面遇到的是,在 使用ssh框架的時候,在action裡面不要使用,get或者 set來為方法命名。這樣反射的時候,會帶著不可調和的bug繼續帶著web程式 在伺服器上跑。糾結再三,發現報了一個異常,他去掉了我的get,然後留了那個方法後面的字元。以及,在使用oracle的時候,開始少寫了一個藥品生產日期的欄位。然後在修改表結構的時候,多加了一個欄位叫做date。然後 同樣悲劇了。其實 這些都是隱含的規定,慢慢慢慢才知道的,就跟我們在定義變數的時候 使用 class 或者 interface一樣。是不應該這樣做的。也是極力要避免的,事實上,如果不避免,編譯器會提醒你的。如果編譯器不能勾引起重視,那麼在運行的時候一定會。
二、Set介面
存儲特點:存儲唯一無序的數據,即使數據重覆添加,在數據顯示的時候也不會重覆。
常用實現類: HashSet
常用方法:
添加:add(Object o);
判斷:isEmpty()
刪除:remove()
包含:contains()//判斷集合中是否包含該元素
遍歷:兩種方式:
Foreach
迭代 使用迭代器
Iterator it = 集合.iterator();
While(it.hasNext()){
It.next();//獲取每一個數據,返回數據類型為:Object。
}
三、Map集合
a) 實現類HashMap
b) 存儲特點:以鍵值對方式存儲(key-value) key值不允許重覆,value值可以重覆
c) 常用方法:
i. 添加:put(key,value)
ii. 刪除 remove(key)
iii. 查看 get(key)單個數據訪問
iv. 獲取key值集合
v. keySet()返回類型是 keySet
vi. 獲取value值的集合 返回 Collection值類型
vii. 判斷key值是否存在
viii. containskey(key)
(d) 添加泛型 Map<String,User> map = new HashMap<String,Map>();
限定key值為String類型,限定value為User類型
Java中的集合框架在添加數據時都會向上轉型為Object類型,那麼取出數據時需要強制類型轉換,但是如果集合框架添加了泛型則取出數據時,不需強轉。
練習:DVD的管理 和添加
晚一點兒 再弄 先打游戲。跟朋友一起
自己寫常式的時候竟然還發現了 這個 addAll();方法。竟然不知道。現在 用一下吧。
剩下的代碼分開寫吧。因為這裡面有一個 關於 ConcurrentModificationException 要說明一下。因為 確實 可能出現過bug。簡要說明就是 遍歷就是遍歷,如果在遍歷的時候被遍歷的集合中的元素數量發生改變的話,那麼遍歷就不能正常進行,帶來數量改變的就只有add 和 remove的操作,所以在遍歷的過程中是不能夠執行這兩個方法的,合理的方法是,在遍歷的過程中,對要增加和刪除的操作標記好當前元素在集合中的位置【因為 list有序】,然後遍歷完成之後,在找到對應元素增加或者刪除。
【理解成有個傻孩子,在數糖果,你在他數的過程中,是不能往裡面增加糖果,或者拿走糖果的,如果這樣做,他就一定會數亂。數亂就一定會報ConcurrentModificationException】
示例代碼:
package CollectionPart; public class EntityForArrayList { private int id; private String name; private int gender;//0男;1女 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getGender() { return gender; } public void setGender(int gender) { this.gender = gender; } @Override public String toString() { return "EntityForArrayList [id=" + id + ", name=" + name + ", gender=" + gender + "]"; } public EntityForArrayList(int id, String name, int gender) { this.id = id; this.name = name; this.gender = gender; } public EntityForArrayList() { super(); } }
package CollectionPart; import java.util.ArrayList; import java.util.List; public class ArrayList1 { public static void main(String[] args) { List myList = new ArrayList(); EntityForArrayList entity1 = new EntityForArrayList(1, "letben", 0); EntityForArrayList entity2 = new EntityForArrayList(2, "lifei", 1); myList.add(entity1); myList.add(entity2); List<EntityForArrayList> myList2 = new ArrayList(); EntityForArrayList entity3 = new EntityForArrayList(3,"life",1); //添加單個元素的方法 myList2.add(entity3); //添加集合的方法 myList2.addAll(myList); // for (EntityForArrayList entityForArrayList : myList2) { // System.out.println(entityForArrayList); // } EntityForArrayList entity4 = new EntityForArrayList(4, "forAdd", 0); //在指定位置之後添加元素 myList2.add(1, entity4); // for (EntityForArrayList entityForArrayList : myList2) { // System.out.println(entityForArrayList); // } EntityForArrayList entity5 = new EntityForArrayList(5, "forChange", 1); myList2.set(1, entity5); /** * 背景:拿到一個集合,要求刪除集合中集合id為5的實體 * 這樣我們就可以進行遍歷。遍歷過程中,進行檢測。然後直接刪除。邏輯上是沒有問題的。 * 但是當我們這樣書寫的時候會報出一個 ConcurrentModificationException。 * 舉個例子來說明這個問題。 * 現在有4顆糖果,分別是紅橙藍紫四個顏色。要求得到一個集合裡面沒有橙色糖果。我們要做的事情是去遍歷給出的糖果,作出判定——這個糖果是不是橙色的。 * 如果是,就拿出來。當我們要把這顆糖果拿出來的時候,我們要遍歷的集合的個數已經發生了改變,不再是開始給出的包含4顆糖果的集合了。遍歷屬於單獨的對於整體的元素的個數的一個把握。 * 如果數量變了,那麼迭代就可能發生異常。試想,假設這個任務是分給兩個小朋友做得。一個小朋友負責遍歷糖果,另一個小朋友負責判定是否橙色並取出。 * 如果做遍歷的小朋友,每次遍歷,糖果的數量都是不確定的,那麼他在數起來的時候,就會出現問題。所以遍歷的時候不能更改元素的個數。添加也會報出異常。 * */ /*for (EntityForArrayList entityForArrayList : myList2) { if(entityForArrayList.getId()==5){//噹噹前元素為非最後一個的時候還不會報ConcurrentModificationException異常 myList2.remove(entityForArrayList); } System.out.println(entityForArrayList); }*/ /** * concurrentModificationException 演示2: * 添加元素時候,因為讓小朋友遍歷的時候數著數著,偷偷往集合裡面添加元素,那麼他也有可能數著數著數亂了。所以這種情況下也是會爆出異常的。 */ /*int i =0; for (EntityForArrayList entityForArrayList : myList2) { i++; if(i==2){ myList2.add(entity4); } System.out.println(entityForArrayList); }*/ /** * 當然如果 只是單純的換糖果是不會影響的。【當然只是不影響遍歷,對於顏色的要求還要另外寫邏輯實現,要判斷用來替換的糖果是否是橙色的】 */ int j =0; for (EntityForArrayList entityForArrayList : myList2) { j++; if(j==2){ myList2.set(2,entity4); } System.out.println(entityForArrayList); } System.out.println("-------------"); System.out.println(myList2.get(2)); System.out.println(myList2.size()); } }