Java集合框架01

集合框架· ArrayList 和 Vector

 對象數組的概述和使用

 * 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類的方法
        }
    }
}
Collection

 

集合的由來及集合繼承體系圖

 * A:集合的由來
  * 數組的長度是固定的,當添加的元素超過了數組的長度時須要對數組從新定義
  * Java內部給咱們提供了集合類,能存儲任意對象,長度能夠改變,隨着元素的增長而增長面試

* B:數組和集合的區別
  * 區別一:
    * 數組 既能夠存儲基本數據類型,又能夠存儲引用數據類型;基本數據類型存儲的是值,引用數據類型存儲的是地址值
    * 集合 只能存儲引用數據類型;若是要存儲基本數據類型,就須要進行裝箱數組

  * 區別二:
    * 數組的長度是固定的,不能自動增加
    * 集合的長度是可變的,能夠根據元素的增長而增加安全

* C:數組和集合何時用
  * 若是元素的個數是固定的,推薦用數組
  * 若是元素的個數不是固定的,推薦用集合數據結構

* D:集合繼承體系圖併發

 

Collection集合的基本功能測試

* 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(' ');
        }
    }
toString

 

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方法
    }
}
ArrayList

 

集合轉數組遍歷

* 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]);
        }
    }
}
ArrayList

 

 

Collection集合的帶All功能測試

* 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);
    }
}
ArrayList

 

 

迭代器遍歷

* 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());
        }
    }
}
Iterator

 

 

迭代器的原理和源碼解析

* 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();
            }
        }
Iterator源碼

 

 

List集合的特有功能概述和測試

* 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);
    }
}
List

 

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());
        }
    }
}
Test1

 

 

併發修改異常

* 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);

    }
}
ListIterator

 

 

 

ListIterator

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()); // 獲取元素,並將指針向前移動
        }

    }
}
ListIterator

 

Vector的特有功能

* 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()); // 獲取集合中的元素
        }
    }
}
Vector

 

數據結構之數組和鏈表

* 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;
        }
    }
LinkedList源碼 明確查找元素從哪裏開始

 

 

List的三個子類的特色

* A:List的三個子類的特色

  * ArrayList:
    底層數據結構是數組,查詢快,增刪慢
    線程不安全,效率高

  * Vector:
    底層數據結構是數組,查詢快,增刪慢
    線程安全,效率低
    Vector相對ArrayList查詢慢(線程安全)
    Vector相對LinkedList增刪滿(數據結構)

  * LinkedList:
    底層數據結構是鏈表,查詢慢,增刪快
    線程不安全,效率高

  * Vector和ArrayList的區別
    Vector是線程安全的,效率低
    ArrayList是線程不安全的,效率高
    共同的:都是數組實現的

  * ArrayList和LinkedList的區別
    ArrayList底層是數組結構,查詢和修改快
    LinkedList底層是鏈表結構,查詢慢修改快
    共同的:都是線程不安全的

* List的三個兒子的使用
  * 查詢多  -> ArrayList
  * 增刪多  -> LinkedList
  * 都多     -> ArrayList

  * Vector通常只在面試的時候會問

相關文章
相關標籤/搜索