public class Student 2 { 3 // 成員變量 4 private String name; 5 private int age; 6 7 // 構造方法 8 public Student() 9 { 10 super(); 11 } 12 13 public Student(String name, int age) 14 { 15 super(); 16 this.name = name; 17 this.age = age; 18 } 19 20 // 成員方法 21 // getXxx()/setXxx() 22 public String getName() 23 { 24 return name; 25 } 26 27 public void setName(String name) 28 { 29 this.name = name; 30 } 31 32 public int getAge() 33 { 34 return age; 35 } 36 37 public void setAge(int age) 38 { 39 this.age = age; 40 } 41 42 @Override 43 public String toString() 44 { 45 return "Student [name=" + name + ", age=" + age + "]"; 46 } 47 }
1 /** 2 把5個學生的信息存儲到數組中,並遍歷數組,獲取得到每一個學生信息。 3 * 學生:Student 4 * 成員變量:name,age 5 * 構造方法:無參,帶參 6 * 成員方法:getXxx()/setXxx() 7 * 分析: 8 * A:創建學生類。 9 * B:創建學生數組(對象數組)。 10 * C:創建5個學生對象,並賦值。 11 * D:把C步驟的元素,放到數組中。 12 * E:遍歷學生數組。 13 * */ 14 15 public class Practice 16 { 17 public static void main(String[] args) 18 { 19 // 創建學生數組(對象數組)。 20 Student[] students = new Student[5]; 21 // for (int x = 0; x < students.length; x++) 22 // { 23 // System.out.println(students[x]); 24 // } 25 // System.out.println("---------------------"); 26 27 // 創建5個學生對象,並賦值。 28 Student s1 = new Student("小明", 27); 29 Student s2 = new Student("小紅", 30); 30 Student s3 = new Student("小強", 30); 31 Student s4 = new Student("旺財", 12); 32 Student s5 = new Student("張三", 35); 33 34 // 將對象放到數組中。 35 students[0] = s1; 36 students[1] = s2; 37 students[2] = s3; 38 students[3] = s4; 39 students[4] = s5; 40 41 // 遍歷 42 for (int x = 0; x < students.length; x++) 43 { 44 //System.out.println(students[x]); 45 Student s = students[x]; 46 System.out.println(s.getName()+"---"+s.getAge()); 47 } 48 } 49 }
15.02 對象數組的內存圖解
15.03 集合的由來及與數組的區別
集合類的由來:面向對象語言對事物的體現都是以對象的形式,所以為了方便對多個對象的操作,Java就提供了集合類。
數組和集合類同的區別:
數組可以存儲同一種類型的基本數據也可以存儲同一種類型的對象,但長度是固定的
集合只可以存儲不同類型的對象,長度是可變的
集合類的特點:集合只用於存儲對象,集合長度是可變的,集合可以存儲不同類型的對象。
15.04 集合的繼承體系圖解
集合容器因為內部的數據結構不同,有多種具體容器,根據共性內容不斷的向上抽取,就形成了集合框架。
框架的頂層Collection接口
15.05 Collection集合的功能概述
Collection 層次結構中的根接口。Collection 表示一組對象,這些對象也稱為 collection 的元素。一些 collection 允許有重復的元素,而另一些則不允許。一些 collection 是有序的,而另一些則是無序的。JDK 不提供此接口的任何直接實現:它提供更具體的子接口(如 Set 和 List)實現。此接口通常用來傳遞 collection,並在需要最大普遍性的地方操作這些 collection。
15.06 Collection集合的基本功能測試
成員方法:
1. boolean add(Ee):確保此 collection 包含指定的元素(可選操作)。
2. boolean remove(Objecto):從此 collection 中移除指定元素的單個實例,如果存在的話(可選操作)。
3. void clear():移除此 collection 中的所有元素(可選操作)。
4. boolean contains(Objecto):如果此 collection 包含指定的元素,則返回 true。
5. boolean isEmpty():如果此 collection 不包含元素,則返回 true。
6. int size():返回此 collection 中的元素數。
例:
1 // 創建集合對象 2 // Collection c = new Collection(); //錯誤,因為接口不能實例化 3 Collection c = new ArrayList(); 4 c.add("hello"); 5 c.add("world"); 6 c.add("java"); 7 // c.clear();//移除所有元素 8 // System.out.println("remove:" + c.remove("hello"));//移除一個元素 9 // System.out.println("remove:" + c.remove("javaee")); 10 // 判斷集合中是否包含指定的元素 11 System.out.println("contains:"+c.contains("hello"));//contains:true 12 System.out.println("contains:"+c.contains("android"));//contains:false 13 //判斷集合是否為空 14 System.out.println("isEmpty:"+c.isEmpty());//isEmpty:false 15 //元素的個數 16 System.out.println("size:"+c.size());//size:3 17 System.out.println("c:" + c);//c:[hello, world, java]
15.07 Collection集合的高級功能測試
成員方法:
1. boolean addAll(Collection<? extends E> c):
將指定 collection 中的所有元素都添加到此 collection 中(可選操作)。
2. boolean removeAll(Collection<?> c):
移除此 collection 中那些也包含在指定 collection 中的所有元素(可選操作)。
3. boolean containsAll(Collection<?> c):
如果此 collection 包含指定 collection 中的所有元素,則返回 true。
4. boolean retainAll(Collection<?> c):
僅保留此 collection 中那些也包含在指定 collection 的元素(可選操作)。換句話說,移除此 collection 中未包含在指定 collection 中的所有元素。
例:
c1.addAll(c2);//將c2集合中的所有元素添加到c1集合中,c1變c2不變 c1.removeAll(c2);//將c1集合中與c2集合相同的所有元素刪除,只要有一個相同的就返回true c1.containsAll(c2);//判斷c1集合中的元素是否包含c2中的全部元素,全部包含則返回true c1.retainAll(c2);//將c1集合中與c2集合相同的元素保留,刪除其他元素,返回值表示c1集合是否發生變化,發生變化返回true,沒有變化返回false
15.08 集合的遍歷之集合轉數組遍歷
Object[] toArray():返回包含此 collection 中所有元素的數組。
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 創建集合 6 Collection c = new ArrayList(); 7 c.add("hello"); 8 c.add("world"); 9 c.add("java"); 10 11 Object[] objs = c.toArray(); 12 for (int i = 0; i < objs.length; i++) 13 { 14 //向下轉為String類型 15 String s = (String)objs[i]; 16 System.out.println(s+":"+s.length()); 17 } 18 } 19 }
運行結果:
hello:5 world:5 java:4
15.09 Collection存儲自定義對象並遍歷案例(使用數組)
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 創建集合 6 Collection c = new ArrayList(); 7 //創建學生對象並添加到集合 8 c.add(new Student("小明",23)); 9 c.add(new Student("小紅",32)); 10 c.add(new Student("小強",14)); 11 c.add(new Student("旺財",8)); 12 c.add(new Student("張三",16)); 13 14 Object[] objs = c.toArray(); 15 for (int i = 0; i < objs.length; i++) 16 { 17 Student s = (Student)objs[i]; 18 System.out.println(s.getName()+":"+s.getAge()); 19 } 20 } 21 }
運行結果:
小明:23 小紅:32 小強:14 旺財:8 張三:16
15.10 集合的遍歷之迭代器遍歷
Iterator<E> iterator():返回在此 collection 的元素上進行迭代的迭代器。
例:
1 // 創建集合 2 Collection c = new ArrayList(); 3 //創建元素並添加到集合 4 c.add("hello"); 5 c.add("world"); 6 c.add("java"); 7 //獲取迭代器,實際返回的是子類對象,多態 8 Iterator it = c.iterator(); 9 while(it.hasNext()) 10 { 11 System.out.println(it.next()); 12 }
15.11 Collection存儲自定義對象並遍歷案例(使用迭代器)
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 創建集合 6 Collection c = new ArrayList(); 7 //創建學生對象並添加到集合 8 c.add(new Student("小明",23)); 9 c.add(new Student("小紅",32)); 10 c.add(new Student("小強",14)); 11 c.add(new Student("旺財",8)); 12 c.add(new Student("張三",16)); 13 14 Iterator it = c.iterator(); 15 while(it.hasNext()) 16 { 17 Student s = (Student)it.next(); 18 System.out.println(s.getName()+":"+s.getAge()); 19 } 20 } 21 }
15.12 迭代器使用的問題探討
1.使用迭代器獲取元素的兩種方式:
方式1:
Iterator it = c.iterator(); while(it.hasNext()) { Student s = (Student)it.next(); System.out.println(s.getName()+":"+s.getAge()); }
方式2:
for(Iterator it = c.iterator();it.hasNext();) { Student s = (Student)it.next(); System.out.println(s.getName()+":"+s.getAge()); }
使用方式2的好處:it在for循環結束后就變成垃圾,效率較高
2.不要多次使用it.next()方法
例:
Iterator it = c.iterator();
while(it.hasNext()) { System.out.println(((Student)it.next()).getName()); System.out.println(((Student)it.next()).getAge()); }
上面的代碼表示獲取的是第1個學生的姓名,第2個學生的年齡,以此類推,如果集合中的元素是奇數個,則會報NoSuchElementException錯誤
15.13 集合的使用步驟圖解
集合的使用步驟:
1. 創建集合對象
2. 創建元素對象
3. 將元素添加到集合
4. 遍歷集合
4.1 通過集合對象獲取迭代器對象
4.2 通過迭代器對象的hasNext()方法判斷是否有元素
4.3 通過迭代器對象的Next()方法獲取元素並移動到下一個位置
15.14 迭代器的原理及源碼解析
原理:
假設迭代器定義的是一個類,那么就可以創建該類的對象,調用該類的方法來實現集合的遍歷,但是Java中提供了很多的集合類,而這些集合類的數據結構是不同的,所以存儲的方式和遍歷的方式也應該是不同的,進而它們的遍歷方式也應該是不一樣的。最終就沒有定義迭代器類
而無論使用哪種集合都應該具備獲取元素的操作,並且最好再輔助與判斷功能,也就是說判斷功能和獲取功能應該是一個集合遍歷所具備的,而每種集合的方式又不太一樣,所以將這兩個功能給提取出來,並不提供具體實現,這種方式就是接口,而真正具體的實現類在具體的子類中以內部類的方式體現的
源碼:
public interface Iterator { boolean hasNext(); Object next(); } public interface Iterable { Iterator iterator(); } public interface Collection extends Iterable { Iterator iterator(); } public interface List extends Collection { Iterator iterator(); } public class ArrayList implements List { public Iterator iterator() { return new Itr(); } //內部類 private class Itr implements Iterator { public boolean hasNext() {} public Object next(){} } } Collection c = new ArrayList(); c.add("hello"); c.add("world"); c.add("java"); Iterator it = c.iterator(); //new Itr(); while(it.hasNext()) { String s = (String)it.next(); System.out.println(s); }
15.15 Collection存儲字符串並遍歷
1 import java.util.ArrayList; 2 import java.util.Collection; 3 import java.util.Iterator; 4 5 public class Practice 6 { 7 8 public static void main(String[] args) 9 { 10 11 // 創建集合 12 Collection c = new ArrayList(); 13 14 //添加字符串 15 c.add("hello"); 16 c.add("你好"); 17 c.add("world"); 18 c.add("java"); 19 c.add("旺財"); 20 //通過集合對象獲取迭代器對象 21 22 Iterator it = c.iterator(); 23 while(it.hasNext()) 24 25 { 26 String s = (String)it.next(); 27 28 System.out.println(s); 29 } 30 31 } 32 33 }
15.16 Collection存儲學生對象並遍歷
1 import java.util.ArrayList; 2 import java.util.Collection; 3 import java.util.Iterator; 4 5 public class Practice 6 { 7 public static void main(String[] args) 8 { 9 // 創建集合 10 Collection c = new ArrayList(); 11 //創建學生對象並添加到集合 12 c.add(new Student("小明",23)); 13 c.add(new Student("小紅",32)); 14 c.add(new Student("小強",14)); 15 c.add(new Student("旺財",8)); 16 c.add(new Student("張三",16)); 17 18 Iterator it = c.iterator(); 19 while(it.hasNext()) 20 { 21 Student s = (Student)it.next(); 22 System.out.println(s.getName()+":"+s.getAge()); 23 } 24 } 25 }
15.17 List存儲字符串並遍歷
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 創建集合 6 List list = new ArrayList(); 7 list.add("hello"); 8 list.add("world"); 9 list.add("java"); 10 11 Iterator it = list.iterator(); 12 while(it.hasNext()) 13 { 14 String s = (String)it.next(); 15 System.out.println(s); 16 } 17 } 18 }
15.18 List集合的特點
List接口概述:有序的(存取順序一致)collection(也稱為序列)。此接口的用戶可以對列表中每個元素的插入位置進行精確地控制。用戶可以根據元素的整數索引(在列表中的位置)訪問元素,並搜索列表中的元素。
特點:與 set 不同,列表通常允許重復的元素。
15.19 List存儲學生對象並遍歷
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 創建集合 6 List list = new ArrayList(); 7 //創建學生對象並添加到集合 8 list.add(new Student("小明",23)); 9 list.add(new Student("小紅",32)); 10 list.add(new Student("小強",14)); 11 list.add(new Student("旺財",8)); 12 list.add(new Student("張三",16)); 13 14 Iterator it = list.iterator(); 15 while(it.hasNext()) 16 { 17 Student s = (Student)it.next(); 18 System.out.println(s.getName()+":"+s.getAge()); 19 } 20 } 21 }
15.20 List集合的特有功能概述和測試
1. void add(int index,Eelement):
在列表的指定位置插入指定元素(可選操作)。
2. Eremove(int index):
移除列表中指定位置的元素(可選操作)。
3. Eget(int index):
返回列表中指定位置的元素。
4. Eset(int index, Eelement):
用指定元素替換列表中指定位置的元素(可選操作)。
例:
list.add(2,"javaee");//在2的位置插入javaee,改變集合長度
list.get(2)//返回集合中2位置上的元素,不改變集合長度
list.remove(1)//刪除集合中1位置上的元素,返回被刪除的元素,改變集合長度
list.set(2, "javaee")//將集合中2位置上的元素替換為javaee,返回被替換的元素,不改變集合長度
15.21 List集合的特有遍歷功能
1 for (int i = 0; i < list.size(); i++) 2 3 { 4 5 String s = (String)list.get(i); 6 7 System.out.println(s); 8 9 }
15.22 List存儲自定義對象並遍歷(使用List特有功能遍歷)
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 創建集合 6 List list = new ArrayList(); 7 //創建學生對象並添加到集合 8 list.add(new Student("小明",23)); 9 list.add(new Student("小紅",32)); 10 list.add(new Student("小強",14)); 11 list.add(new Student("旺財",8)); 12 list.add(new Student("張三",16)); 13 14 for (int i = 0; i < list.size(); i++) 15 { 16 Student s =(Student)list.get(i); 17 System.out.println(s.getName()+":"+s.getAge()); 18 } 19 } 20 }
15.23 ListIterator的特有功能
ListIterator<E> listIterator():
返回此列表元素的列表迭代器(按適當順序)。
注意:ListIterator可以實現逆向遍歷,但是必須先正向遍歷,才能逆向遍歷
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 創建集合 6 List list = new ArrayList(); 7 8 list.add("hello"); 9 list.add("world"); 10 list.add("java"); 11 //列表迭代器 12 ListIterator lit = list.listIterator(); 13 //正向遍歷 14 while(lit.hasNext()) 15 { 16 String s = (String)lit.next(); 17 System.out.println(s); 18 } 19 System.out.println("-----"); 20 //逆向遍歷 21 while(lit.hasPrevious()) 22 { 23 //獲取上一個元素 24 String s = (String)lit.previous(); 25 System.out.println(s); 26 } 27 28 } 29 }
運行結果:
hello
world
java
-----
java
world
hello
15.24 並發修改異常的產生原因及解決方案
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 創建集合 6 List list = new ArrayList(); 7 8 list.add("hello"); 9 list.add("world"); 10 list.add("java"); 11 Iterator it = list.iterator(); 12 while(it.hasNext()) 13 { 14 String s = (String)it.next(); 15 if(s.equals("world")) 16 list.add("javaee"); 17 } 18 System.out.println(list); 19 } 20 }
上面的代碼會運行錯誤,發生ConcurrentModificationException異常
錯誤產生原因:迭代器是依賴於集合存在的,在迭代的過程中使用集合的方法添加元素迭代器是不知道的,所以報錯,並發修改異常
解決方案:1.用迭代器迭代元素時使用迭代器修改元素(ListIterator列表迭代器),添加的元素在迭代的元素后面
2.用集合遍歷元素,用集合修改元素(for循環),添加的元素在最后
15.25 數據結構之棧和隊列
數據結構:數據的組織方式
15.26 數據結構之數組和鏈表
數組:存儲同一種類型的多個元素的容器
鏈表:由一個鏈子把多個節點(數據和節點)連起來組成的數據
15.27 List的三個子類的特點
ArrayList:底層數據結構是數組,查詢快,增刪慢,是不同步的,線程不安全,效率高
Vector:底層數據結構是數組,查詢快,增刪慢,是同步的,線程安全,效率低
LinkedList:底層數據結構是鏈表,查詢慢,增刪快,是不同步的,線程不安全,效率高