* A:案例演示
* 需求:我有5個學生,請把這5個學生的信息存儲到數組中,並遍歷數組,獲取到每一個學生的信息java
Student[] arr = new Student[5]; arr[0] = new Student("張三", 23); arr[1] = new Student("李四", 24); arr[2] = new Student("王五", 25); arr[3] = new Student("趙六", 26); arr[4] = new Student("周七", 27); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); }
* B:畫圖演示
* 把學生數組的案例畫圖講解
* 數組和集合存儲引用數據類型,存的都是地址值node
package com.heima.collection; import com.heima.bean.Student; public class Demo1_Array { public static void main(String[] args) { // int[] arr = new int[5]; // 建立基本數據類型數組 Student[] arr = new Student[5]; // 建立引用數據類型數組 arr[0] = new Student("張三", 23); // 建立一個學生對象,存儲在數組的第一個位置 arr[1] = new Student("李四", 24); arr[2] = new Student("王五", 25); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); // 默認調用toString的方法,若是Student類沒有重寫toString方法,則默認調用Object類的方法 } } }
* A:集合的由來
* 數組的長度是固定的,當添加的元素超過了數組的長度時須要對數組從新定義
* Java內部給咱們提供了集合類,能存儲任意對象,長度能夠改變,隨着元素的增長而增長面試
* B:數組和集合的區別
* 區別一:
* 數組 既能夠存儲基本數據類型,又能夠存儲引用數據類型;基本數據類型存儲的是值,引用數據類型存儲的是地址值
* 集合 只能存儲引用數據類型;若是要存儲基本數據類型,就須要進行裝箱數組
* 區別二:
* 數組的長度是固定的,不能自動增加
* 集合的長度是可變的,能夠根據元素的增長而增加安全
* C:數組和集合何時用
* 若是元素的個數是固定的,推薦用數組
* 若是元素的個數不是固定的,推薦用集合數據結構
* D:集合繼承體系圖併發
* A:案例演示app
基本功能演示 boolean add(E e) boolean remove(Object o) void clear() boolean contains(Object o) boolean isEmpty() int size()
* B:注意
* collectionXxx.java 使用了未經檢查或不安全的操做
* 要了解詳細信息,請使用 -Xlint:inchecked 從新編譯
* java編譯器認爲該程序存在安全隱患框架
public String toString() { Iterator<E> it = iterator(); if (! it.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { E e = it.next(); sb.append(e == this ? "(this Collection)" : e); if (! it.hasNext()) return sb.append(']').toString(); sb.append(',').append(' '); } }
package com.heima.collection; import java.util.ArrayList; import java.util.Collection; import com.heima.bean.Student; @SuppressWarnings({ "rawtypes", "unchecked" }) public class Demo2_Collection { public static void main(String[] args) { Collection c = new ArrayList(); // 父類引用指向子類對象 // demo1(c); demo2(c); } public static void demo2(Collection c) { c.add("a"); c.add("b"); c.add("c"); c.add("d"); c.remove("c"); // 刪除指定元素 System.out.println(c); System.out.println(c.contains("a")); // 判斷是否包含指定元素 c.clear(); // 完全清空集合 System.out.println(c); System.out.println(c.isEmpty()); // 判斷是不是空集合 System.out.println(c.size()); // 獲取集合中包含的元素的個數,相似於字符串中的length()方法 } public static void demo1(Collection c) { // add方法: 若是是List集合,一直都返回true,由於List集合中是能夠存儲重複元素的 // 若是是set 集合,當存儲重複元素時,就會返回false boolean b1 = c.add("abc"); // 能夠添加任意對象,任意對象都是Object的子類 boolean b2 = c.add(true); // 自動裝箱 new Boolean(true); boolean b3 = c.add(100); // 自動裝箱 new Integer(100); boolean b4 = c.add(new Student("張三", 23)); boolean b5 = c.add("abc"); // 都是true System.out.println(b1); System.out.println(b2); System.out.println(b3); System.out.println(b4); System.out.println(b5); System.out.println(c); // ArrayList的爺爺類重寫了toString方法 } }
* A:集合的遍歷
* 其實就是依次獲取集合中的每個元素eclipse
* B:案例演示
* 把集合轉換成數組,能夠實現集合的遍歷
* toArray()
Collection c = new ArrayList(); c.add(new Student("張三", 23)); // Object obj = new Student("張三", 23) c.add(new Student("李四", 24)); c.add(new Student("王五", 25)); c.add(new Student("趙六", 26)); Object[] arr = coll.toArray; // 將集合轉換爲數組 for (int i = 0; i < arr.length; i++) { Student s = (Student)arr[i]; // 強轉成Student System.out.println(s.getName() + "," + s.getAge()); }
package com.heima.collection; import java.util.ArrayList; import java.util.Collection; import com.heima.bean.Student; @SuppressWarnings({ "rawtypes", "unchecked" }) public class Demo3_Collection { public static void main(String[] args) { // demo1(); // demo2(); } public static void demo2() { Collection c = new ArrayList(); c.add(new Student("張三", 23)); // 向數組內存入自定義的引用對象 c.add(new Student("李四", 24)); c.add(new Student("王五", 25)); c.add(new Student("趙六", 26)); Object[] arr = c.toArray(); // 向上轉型 提高爲Object類 for (int i = 0; i < arr.length; i++) { // System.out.println(arr[i]); Student s = (Student) arr[i]; // 強制向下轉型 System.out.println(s.getName() + "..." + s.getAge()); } } public static void demo1() { Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); Object[] arr = c.toArray(); // 將集合轉換成數組 for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } }
* A:案例演示
帶All的功能演示
boolean addAll(Collection c) boolean removeAll(Collection c) boolean containsAll(Collection c) boolean retainAll(Collection c)
package com.heima.collection; import java.util.ArrayList; import java.util.Collection; public class Demo4_Collection { public static void main(String[] args) { // demo1(); // 總體添加 // demo2(); // 刪除交集 // demo3(); // 是否包含 // demo4(); // 取交集 } public static void demo4() { Collection c1 = new ArrayList(); c1.add("a"); c1.add("b"); c1.add("c"); c1.add("d"); Collection c2 = new ArrayList(); c2.add("a"); c2.add("b"); c2.add("z"); c2.add("c"); c2.add("d"); boolean b = c1.retainAll(c2); // 取交集,若是調用的集合改變就返回true,若是調用的集合不變就返回false System.out.println(b); System.out.println(c1); } public static void demo3() { Collection c1 = new ArrayList(); c1.add("a"); c1.add("b"); c1.add("c"); c1.add("d"); Collection c2 = new ArrayList(); c2.add("a"); c2.add("b"); c2.add("z"); boolean b = c1.containsAll(c2); // 判斷調用的集合是否包含傳入的集合,若是出現一個元素不包含就返回false,能夠有重複 System.out.println(b); } public static void demo2() { Collection c1 = new ArrayList(); c1.add("a"); c1.add("b"); c1.add("c"); c1.add("d"); Collection c2 = new ArrayList(); c2.add("a"); c2.add("b"); c2.add("z"); boolean b = c1.removeAll(c2); // 若是有交集,就刪除並返回true; 若是沒有交集就不刪除而且返回false System.out.println(b); System.out.println(c1); } public static void demo1() { Collection c1 = new ArrayList(); c1.add("a"); c1.add("b"); c1.add("c"); c1.add("d"); Collection c2 = new ArrayList(); // alt + shift + r 能夠總體更名 c2.add("a"); c2.add("b"); c2.add("c"); c2.add("d"); c1.addAll(c2); // 將c2中的每個元素都 添加到c1中 c1.add(c2); // 將c2整個集合當作 一個對象 添加到c1中 System.out.println(c1); } }
* A:迭代器概述
* 集合是用來存儲元素的,存儲的元素要查看,那麼就須要迭代(遍歷)
* 案例演示
迭代器的使用
Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); Iterator it = c.iterator(); while (it.hasNext()) { System.out.println(it.next()); }
package com.heima.collection; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import com.heima.bean.Student; public class Demo5_Collection { public static void main(String[] args) { // demo1(); // demo2(); } public static void demo2() { // 迭代自定義類 Collection c = new ArrayList(); c.add(new Student("張三", 23)); // 自動提高爲Object類 c.add(new Student("李四", 24)); c.add(new Student("王五", 25)); c.add(new Student("趙六", 26)); // 獲取迭代器 Iterator it = c.iterator(); while (it.hasNext()) { // System.out.println(it.next()); Student s = (Student) it.next(); // 向下轉型,注意next方法調用時的指針位置變化 System.out.println(s.getName() + "..." + s.getAge()); } } public static void demo1() { Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); // 對集合中的元素進行迭代(遍歷) Iterator it = c.iterator(); // 獲取迭代器 /* * boolean b1 = it.hasNext(); // 判斷集合中是否有元素 * System.out.println(b1); // * Object obj1 = it.next(); // next方法獲取相應元素,而且將指針向後移動一位 * System.out.println(obj1); */ while (it.hasNext()) { System.out.println(it.next()); } } }
* A:迭代器原理
* 迭代器是對集合進行遍歷,而每個集合內部的存儲結構都是不一樣的,因此沒一個集合的存和取的方式都是不同的
* 那麼這就須要在每個類中定義hasNext() 和 next() 方法,這樣作能夠可是會使集合體系過於臃腫
* 迭代器就是將這樣的方法向上抽取出接口,而後在每一個類的內部,定義本身的迭代方法
* 好處:一、規定了整個集合體系的遍歷方式都是hasNext() 和next() 方法;二、代碼由底層內部實現,使用者不用管怎麼實現,會用便可
* B:迭代器源碼分析
* 一、在eclipse 中ctrl + shift + t 找到ArrayList類
* 二、ctrl + o 查找 iterator() 方法
* 三、查看返回值類型是new Itr(), 說明Itr這個類實現 Iterator接口
* 四、查找 Itr這個內部類,發現重寫了 Iterator中的全部抽象方法
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; // prevent creating a synthetic constructor Itr() {} public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }
* A:List集合的特有功能概述
void add(int index, E element) E remove(int index) E get(int index) E set(int index, E element)
package com.heima.list; import java.util.ArrayList; import java.util.List; public class Demo1_List { public static void main(String[] args) { // demo1(); // 元素添加 // demo2(); // 元素刪除 // demo3(); // remove 注意點 // demo4(); // 經過索引獲取元素 // demo5(); // 指定元素修改 } public static void demo5() { List list = new ArrayList(); list.add(0, "a"); list.add(0, "b"); list.add(0, "c"); list.add(0, "d"); list.set(1, "z"); // 將指定位置的元素修改 System.out.println(list); } public static void demo4() { List list = new ArrayList(); list.add(0, "a"); list.add(0, "b"); list.add(0, "c"); list.add(0, "d"); // Object obj1 = list.get(0); // System.out.println(obj1); // 經過索引遍歷List集合 for (int i = 0; i < list.size(); i++) { // 用 size() 方法 System.out.println(list.get(i)); } } public static void demo3() { List list = new ArrayList(); list.add(111); list.add(222); list.add(333); list.add(444); Object obj1 = list.remove(111); // 刪除的時候不會自動裝箱,111被當成索引,下標就越界了 System.out.println(obj1); } public static void demo2() { List list = new ArrayList(); list.add(0, "a"); list.add(0, "b"); list.add(0, "c"); list.add(0, "d"); Object obj1 = list.remove(0); // 經過索引刪除元素,將被刪除的元素返回 System.out.println(obj1); System.out.println(list); } public static void demo1() { List list = new ArrayList(); // 多態,有弊端,不能訪問子類的特有屬性 list.add("a"); list.add("b"); list.add(0, "c"); // index是元素添加後所在的位置 list.add(0, "d"); // list.add(5, "e"); // 注意索引越界異常,0<=index<=size System.out.println(list); } }
* A:案例演示
* 經過size() 和get() 方法結合使用遍歷
package com.heima.list; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.heima.bean.Student; public class Demo2_List { public static void main(String[] args) { List list = new ArrayList(); list.add(new Student("張三", 23)); // 自動向上轉型爲Object list.add(new Student("李四", 24)); list.add(new Student("王五", 25)); list.add(new Student("趙六", 26)); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); // 經過索引獲取每個元素 Student stu = (Student) list.get(i); System.out.println(stu.getName() + "..." + stu.getAge()); } } }
* A:案例演示
* 需求:若是有一個集合,判斷集合內是否有 "world" 這個元素,若是有,就添加一個 "javaee" 元素
List list = new ArrayList(); list.add("a"); list.add("b"); list.add("world"); list.add("c"); list.add("d"); list.add("e"); ListIterator it = list.listIterator(); while (it.hasNext()) { Object object = it.next(); System.out.println(object); if (object.equals("world")) { list.add("javaee"); it.add("javaee"); } }
* B:ConcurrentModificationException出現
* 迭代器遍歷,集合修改集合
* C:解決方案
* a:迭代器迭代元素,迭代器修改元素 (ListIterator的特有功能 add)
* b:集合遍歷元素,集合修改元素
ListIterator lit = list.listIterator; // 若是向在遍歷的過程當中添加元素,能夠用ListIterator中的add方法 while(lit.hasNext()) {
String str = (String)lit.next; if(str.equals("world")) { lit.add("javaee"); }
}
package com.heima.list; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; public class Demo3_List { public static void main(String[] args) { List list = new ArrayList(); list.add("a"); list.add("b"); list.add("world"); list.add("c"); list.add("d"); list.add("e"); ListIterator it = list.listIterator(); // 獲取迭代器 while (it.hasNext()) { // 判斷集合中是否有元素 String object = (String) it.next(); // 向下轉型 if (object.equals("world")) { // list.add("javaee"); // 遍歷的同時在增長元素,產生併發修改異常 it.add("javaee"); } } System.out.println(list); } }
boolean hasNext() boolean hasPrevious() Object next() Object previous()
package com.heima.list; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; public class Demo4_ListIterator { public static void main(String[] args) { List list = new ArrayList(); list.add("a"); list.add("b"); list.add("world"); list.add("c"); list.add("d"); list.add("e"); ListIterator lit = list.listIterator(); // 獲取迭代器 while (lit.hasNext()) { System.out.println(lit.next()); // 獲取元素,並將指針向後移動 } System.out.println("-----------"); while (lit.hasPrevious()) { System.out.println(lit.previous()); // 獲取元素,並將指針向前移動 } } }
* A:Vector類概述
* B:Vector類特有功能
public void addElements(E obj) public E elementAt(int index) public Enumeration elements()
* C:案例演示
* Vector迭代
package com.heima.list; import java.util.Enumeration; import java.util.Vector; public class Demo5_Vector { public static void main(String[] args) { Vector v = new Vector(); v.addElement("a"); v.addElement("b"); v.addElement("c"); v.addElement("d"); Enumeration en = v.elements(); // 獲取枚舉 while (en.hasMoreElements()) { // 判斷集合中是否有元素 System.out.println(en.nextElement()); // 獲取集合中的元素 } } }
* A:數組
* 查詢快,修改也快
* 增刪慢
* B:鏈表
* 查詢慢,修改野蠻
* 增刪快
Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
* A:List的三個子類的特色
* ArrayList:
底層數據結構是數組,查詢快,增刪慢
線程不安全,效率高
* Vector:
底層數據結構是數組,查詢快,增刪慢
線程安全,效率低
Vector相對ArrayList查詢慢(線程安全)
Vector相對LinkedList增刪滿(數據結構)
* LinkedList:
底層數據結構是鏈表,查詢慢,增刪快
線程不安全,效率高
* Vector和ArrayList的區別
Vector是線程安全的,效率低
ArrayList是線程不安全的,效率高
共同的:都是數組實現的
* ArrayList和LinkedList的區別
ArrayList底層是數組結構,查詢和修改快
LinkedList底層是鏈表結構,查詢慢修改快
共同的:都是線程不安全的
* List的三個兒子的使用
* 查詢多 -> ArrayList
* 增刪多 -> LinkedList
* 都多 -> ArrayList
* Vector通常只在面試的時候會問