Java學習路線:day23 集合

第11章Java集合

Java 集合框架概述

集合框架與數組的對比及概述

/**
 * 一、集合的框架
 *
 * 1.集合、數組都是對多個數據進行存儲操作的結構,簡稱Java容器。
 *   說明;此時的存儲,主要是指能存層面的存儲,不涉及到持久化的存儲(.txt,.jpg,.avi,數據庫中)
 *
 * 2.1數組在存儲多個數據封面的特點:
 *      》一旦初始化以後,它的長度就確定了。
 *      》數組一旦定義好,它的數據類型也就確定了。我們就只能操作指定類型的數據了。
 *      比如:String[] arr;int[] str;
 * 2.2數組在存儲多個數據方面的特點:
 *      》一旦初始化以後,其長度就不可修改。
 *      》數組中提供的方法非常有限,對於添加、刪除、插入數據等操作,非常不便,同時效率不高。
 *      》獲取數組中實際元素的個數的需求,數組沒有現成的屬性或方法可用
 *      》數組存儲數據的特點:有序、可重複。對於無序、不可重複的需求,不能滿足。
 *
 * @author subei
 * @create 2020-05-11 16:23
 */
  • 集合的使用場景

在這裏插入圖片描述
在這裏插入圖片描述

集合框架涉及到的API

  • Java 集合可分爲Collection 和Map 兩種體系

    • Collection接口:單列數據,定義了存取一組對象的方法的集合
      • List:元素有序、可重複的集合
      • Set:元素無序、不可重複的集合
    • Map接口:雙列數據,保存具有映射關係“key-value對”的集合
  • Collection接口繼承樹

在這裏插入圖片描述

  • Map接口繼承樹

在這裏插入圖片描述

/**
 *
 * 二、集合框架
 *      &---Collection接口:單列集合,用來存儲一個一個的對象
 *          &---List接口:存儲有序的、可重複的數據。  -->“動態”數組
 *              &---ArrayList、LinkedList、Vector
 *
 *          &---Set接口:存儲無序的、不可重複的數據   -->高中講的“集合”
 *              &---HashSet、LinkedHashSet、TreeSet
 *
 *      &---Map接口:雙列集合,用來存儲一對(key - value)一對的數據   -->高中函數:y = f(x)
 *          &---HashMap、LinkedHashMap、TreeMap、Hashtable、Properties
 *
 * @author subei
 * @create 2020-05-11 16:23
 */

Collection接口方法

  • Collection 接口是List、Set 和Queue 接口的父接口,該接口裏定義的方法既可用於操作Set 集合,也可用於操作List 和Queue 集合。
  • JDK不提供此接口的任何直接實現,而是提供更具體的子接口(如:Set和List)實現。
  • 在Java5 之前,Java 集合會丟失容器中所有對象的數據類型,把所有對象都當成Object 類型處理;從JDK 5.0 增加了泛型以後,Java 集合可以記住容器中對象的數據類型。

Collection接口中的常用方法1

  1. 添加
    • add(Objectobj)
    • addAll(Collectioncoll)
  2. 獲取有效元素的個數
    • intsize()
  3. 清空集合
    • voidclear()
  4. 是否是空集合
    • boolean isEmpty()
  5. 是否包含某個元素
    • booleancontains(Objectobj):是通過元素的equals方法來判斷是否是同一個對象
    • booleancontainsAll(Collectionc):也是調用元素的equals方法來比較的。拿兩個集合的元素挨個比較。
  6. 刪除
    • boolean remove(Object obj) :通過元素的equals方法判斷是否是要刪除的那個元素。只會刪除找到的第一個元素
    • boolean removeAll(Collection coll):取當前集合的差集
  7. 取兩個集合的交集
    • boolean retainAll(Collection c):把交集的結果存在當前集合中,不影響c
  8. 集合是否相等
    • boolean equals(Object obj)
  9. 轉成對象數組
    • Object[] toArray()
  10. 獲取集合對象的哈希值
    • hashCode()
  11. 遍歷
    • iterator():返回迭代器對象,用於集合遍歷
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

/**
 *
 * 三、Collection接口中的方法的使用
 *
 *
 *
 * @author subei
 * @create 2020-05-11 16:23
 */
public class CollectionTest {

    @Test
    public void test1(){
        Collection coll = new ArrayList();

        //add(Object e):將元素e添加到集合coll中
        coll.add("AA");
        coll.add("BB");
        coll.add(123);  //自動裝箱
        coll.add(new Date());

        //size():獲取添加的元素的個數
        System.out.println(coll.size());    //4

        //addAll(Collection coll1):將coll1集合中的元素添加到當前的集合中
        Collection coll1 = new ArrayList();
        coll1.add(456);
        coll1.add("CC");
        coll.addAll(coll1);

        System.out.println(coll.size());    //6
        System.out.println(coll);

        //clear():清空集合元素
        coll.clear();

        //isEmpty():判斷當前集合是否爲空
        System.out.println(coll.isEmpty());
    }
}

Collection接口中的常用方法2

  • Person類
import java.util.Objects;

/**
 * @author subei
 * @create 2020-05-12 10:11
 */
public class Person {

    private String name;
    private int age;

    public Person() {
        super();
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        System.out.println("Person equals()....");
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }
}
  • 測試類
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

/**
 * Collection接口中聲明的方法的測試
 *
 * 結論:
 * 向Collection接口的實現類的對象中添加數據obj時,要求obj所在類要重寫equals().
 *
 * @author subei
 * @create 2020-05-12 10:06
 */
public class CollectinoTest {

    @Test
    public void test(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);

//        Person p = new Person("Jerry",20);
//        coll.add(p);
        coll.add(new Person("Jerry",20));

        coll.add(new String("Tom"));
        coll.add(false);

        //1.contains(Object obj):判斷當前集合中是否包含obj
        //我們在判斷時會調用obj對象所在類的equals()。
        boolean contains = coll.contains(123);
        System.out.println(contains);
        System.out.println(coll.contains(new String("Tom")));
//        System.out.println(coll.contains(p));//true
        System.out.println(coll.contains(new Person("Jerry",20)));//false -->true

        //2.containsAll(Collection coll1):判斷形參coll1中的所有元素是否都存在於當前集合中。
        Collection coll1 = Arrays.asList(123,4567);
        System.out.println(coll.containsAll(coll1));
    }

}

Collection接口中的常用方法3

  • Person類
import java.util.Objects;

/**
 * @author subei
 * @create 2020-05-12 10:11
 */
public class Person {

    private String name;
    private int age;

    public Person() {
        super();
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        System.out.println("Person equals()....");
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }
}
  • 測試類
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

/**
 * Collection接口中聲明的方法的測試
 *
 * 結論:
 * 向Collection接口的實現類的對象中添加數據obj時,要求obj所在類要重寫equals().
 *
 * @author subei
 * @create 2020-05-12 10:06
 */
public class CollectinoTest {

    @Test
    public void test2(){
        //3.remove(Object obj):從當前集合中移除obj元素。
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        coll.remove(1234);
        System.out.println(coll);

        coll.remove(new Person("Jerry",20));
        System.out.println(coll);

        //4. removeAll(Collection coll1):差集:從當前集合中移除coll1中所有的元素。
        Collection coll1 = Arrays.asList(123,456);
        coll.removeAll(coll1);
        System.out.println(coll);
    }

    @Test
    public void test3(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //5.retainAll(Collection coll1):交集:獲取當前集合和coll1集合的交集,並返回給當前集合
//        Collection coll1 = Arrays.asList(123,456,789);
//        coll.retainAll(coll1);
//        System.out.println(coll);

        //6.equals(Object obj):要想返回true,需要當前集合和形參集合的元素都相同。
        Collection coll1 = new ArrayList();
        coll1.add(456);
        coll1.add(123);
        coll1.add(new Person("Jerry",20));
        coll1.add(new String("Tom"));
        coll1.add(false);

        System.out.println(coll.equals(coll1));
    }

}

Collection接口中的常用方法4

  • Person類
import java.util.Objects;

/**
 * @author subei
 * @create 2020-05-12 10:11
 */
public class Person {

    private String name;
    private int age;

    public Person() {
        super();
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        System.out.println("Person equals()....");
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }
}
  • 測試類
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * Collection接口中聲明的方法的測試
 *
 * 結論:
 * 向Collection接口的實現類的對象中添加數據obj時,要求obj所在類要重寫equals().
 *
 * @author subei
 * @create 2020-05-12 10:06
 */
public class CollectinoTest {

    @Test
    public void test4(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //7.hashCode():返回當前對象的哈希值
        System.out.println(coll.hashCode());

        //8.集合 --->數組:toArray()
        Object[] arr = coll.toArray();
        for(int i = 0;i < arr.length;i++){
            System.out.println(arr[i]);
        }

        //拓展:數組 --->集合:調用Arrays類的靜態方法asList()
        List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"});
        System.out.println(list);

        List arr1 = Arrays.asList(123, 456);
        System.out.println(arr1);//[123, 456]

        List arr2 = Arrays.asList(new int[]{123, 456});
        System.out.println(arr2.size());//1

        List arr3 = Arrays.asList(new Integer[]{123, 456});
        System.out.println(arr3.size());//2

        //9.iterator():返回Iterator接口的實例,用於遍歷集合元素。放在IteratorTest.java中測試
    }
}

Iterator迭代器接口

  • Iterator對象稱爲迭代器(設計模式的一種),主要用於遍歷Collection 集合中的元素。
  • GOF給迭代器模式的定義爲:提供一種方法訪問一個容器(container)對象中各個元素,而又不需暴露該對象的內部細節。迭代器模式,就是爲容器而生。類似於“公交車上的售票員”、“火車上的乘務員”、“空姐”。
  • Collection接口繼承了java.lang.Iterable接口,該接口有一個iterator()方法,那麼所有實現了Collection接口的集合類都有一個iterator()方法,用以返回一個實現了Iterator接口的對象。
  • Iterator 僅用於遍歷集合,Iterator本身並不提供承裝對象的能力。如果需要創建Iterator 對象,則必須有一個被迭代的集合。
  • 集合對象每次調用iterator()方法都得到一個全新的迭代器對象,默認遊標都在集合的第一個元素之前。

在這裏插入圖片描述

使用Iterator遍歷Collection

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * 集合元素的遍歷操作,使用迭代器Iterator接口
 * 內部的方法:hasNext()和 next()
 *
 * @author subei
 * @create 2020-05-12 12:22
 */
public class IteratorTest {

    @Test
    public void test(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        Iterator iterator = coll.iterator();

        //方式一:
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        //報異常:NoSuchElementException
//        //因爲:在調用it.next()方法之前必須要調用it.hasNext()進行檢測。若不調用,且下一條記錄無效,直接調用it.next()會拋出NoSuchElementException異常。
//        System.out.println(iterator.next());

        //方式二:不推薦
//        for(int i = 0;i < coll.size();i++){
//            System.out.println(iterator.next());
//        }

        //方式三:推薦
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

迭代器Iterator的執行原理

在這裏插入圖片描述

Iterator遍歷集合的兩種錯誤寫法

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * 集合元素的遍歷操作,使用迭代器Iterator接口
 * 1.內部的方法:hasNext()和 next()
 * 2.集合對象每次調用iterator()方法都得到一個全新的迭代器對象,默認遊標都在集合的第一個元素之前。
 *
 * @author subei
 * @create 2020-05-12 12:22
 */
public class IteratorTest {

    @Test
    public void test2(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //錯誤方式一:
//        Iterator iterator = coll.iterator();
//        while(iterator.next() != null){
//            System.out.println(iterator.next());
//        }

        //錯誤方式二:
        //集合對象每次調用iterator()方法都得到一個全新的迭代器對象,默認遊標都在集合的第一個元素之前。
        while(coll.iterator().hasNext()){
            System.out.println(coll.iterator().next());
        }
    }
}

Iterator迭代器remove()的使用

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * 集合元素的遍歷操作,使用迭代器Iterator接口
 * 1.內部的方法:hasNext()和 next()
 * 2.集合對象每次調用iterator()方法都得到一個全新的迭代器對象,默認遊標都在集合的第一個元素之前。
 * 3.內部定義了remove(),可以在遍歷的時候,刪除集合中的元素。此方法不同於集合直接調用remove()
 *
 * @author subei
 * @create 2020-05-12 12:22
 */
public class IteratorTest {

    //測試Iterator中的remove()方法
    @Test
    public void test3(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //刪除集合中”Tom”
        //如果還未調用next()或在上一次調用 next 方法之後已經調用了 remove 方法,
        // 再調用remove都會報IllegalStateException。
        Iterator iterator = coll.iterator();
        while(iterator.hasNext()){
//            iterator.remove();
            Object obj = iterator.next();
            if("Tom".equals(obj)){
                iterator.remove();
//                iterator.remove();                
            }
        }

        //遍歷集合
        iterator = coll.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }
}
  • 注意:
    • Iterator可以刪除集合的元素,但是是遍歷過程中通過迭代器對象的remove方法,不是集合對象的remove方法。
    • 如果還未調用next()或在上一次調用next方法之後已經調用了remove方法,再調用remove都會報IllegalStateException

新特性foreach循環遍歷集合或數組

  • Java 5.0 提供了foreach循環迭代訪問Collection和數組。
  • 遍歷操作不需獲取Collection或數組的長度,無需使用索引訪問元素。
  • 遍歷集合的底層調用Iterator完成操作。
  • foreach還可以用來遍歷數組。

在這裏插入圖片描述

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;

/**
 * jdk 5.0 新增了foreach循環,用於遍歷集合、數組
 *
 * @author subei
 * @create 2020-05-12 16:08
 */
public class ForTest {

    @Test
    public void test(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //for(集合元素的類型 局部變量 : 集合對象),內部仍然調用了迭代器。
        for(Object obj : coll){
            System.out.println(obj);
        }
    }

    @Test
    public void test2(){
        int[] arr = new int[]{1,2,3,4,5,6};
        //for(數組元素的類型 局部變量 : 數組對象)
        for(int i : arr){
            System.out.println(i);
        }
    }

    //練習題
    @Test
    public void test3(){
        String[] arr = new String[]{"SS","KK","RR"};

//        //方式一:普通for賦值
//        for(int i = 0;i < arr.length;i++){
//            arr[i] = "HH";
//        }

        //方式二:增強for循環
        for(String s : arr){
            s = "HH";
        }

        for(int i = 0;i < arr.length;i++){
            System.out.println(arr[i]);
        }
    }
}

Collection子接口之一:List接口

  • 鑑於Java中數組用來存儲數據的侷限性,我們通常使用List替代數組
  • List集合類中元素有序、且可重複,集合中的每個元素都有其對應的順序索引。
  • List容器中的元素都對應一個整數型的序號記載其在容器中的位置,可以根據序號存取容器中的元素。
  • JDK API中List接口的實現類常用的有:ArrayList、LinkedList和Vector。

List接口常用實現類的對比

/**
 * 1. List接口框架
 *
 *    |----Collection接口:單列集合,用來存儲一個一個的對象
 *          |----List接口:存儲有序的、可重複的數據。  -->“動態”數組,替換原有的數組
 *              |----ArrayList:作爲List接口的主要實現類;線程不安全的,效率高;底層使用Object[] elementData存儲
 *              |----LinkedList:對於頻繁的插入、刪除操作,使用此類效率比ArrayList高;底層使用雙向鏈表存儲
 *              |----Vector:作爲List接口的古老實現類;線程安全的,效率低;底層使用Object[] elementData存儲
 *
 *
 * 面試題:比較ArrayList、LinkedList、Vector三者的異同?
 *        同:三個類都是實現了List接口,存儲數據的特點相同:存儲有序的、可重複的數據
 *        不同:見上
 *
 * @author subei
 * @create 2020-05-12 20:54
 */

ArrayList的源碼分析

  • ArrayList是List 接口的典型實現類、主要實現類
  • 本質上,ArrayList是對象引用的一個”變長”數組
/** 
 * 2.ArrayList的源碼分析:
 *   2.1 jdk 7情況下
 *      ArrayList list = new ArrayList();//底層創建了長度是10的Object[]數組elementData
 *      list.add(123);//elementData[0] = new Integer(123);
 *      ...
 *      list.add(11);//如果此次的添加導致底層elementData數組容量不夠,則擴容。
 *      默認情況下,擴容爲原來的容量的1.5倍,同時需要將原有數組中的數據複製到新的數組中。
 *
 *      結論:建議開發中使用帶參的構造器:ArrayList list = new ArrayList(int capacity)
 *
 *   2.2 jdk 8中ArrayList的變化:
 *      ArrayList list = new ArrayList();//底層Object[] elementData初始化爲{}.並沒有創建長度爲10的數組
 *
 *      list.add(123);//第一次調用add()時,底層才創建了長度10的數組,並將數據123添加到elementData[0]
 *      ...
 *      後續的添加和擴容操作與jdk 7 無異。
 *   2.3 小結:jdk7中的ArrayList的對象的創建類似於單例的餓漢式,而jdk8中的ArrayList的對象
 *            的創建類似於單例的懶漢式,延遲了數組的創建,節省內存。
 * 
 */

LinkedList的源碼分析

  • 對於頻繁的插入或刪除元素的操作,建議使用LinkedList類,效率較高
  • LinkedList:雙向鏈表,內部沒有聲明數組,而是定義了Node類型的first和last,用於記錄首末元素。同時,定義內部類Node,作爲LinkedList中保存數據的基本結構。

在這裏插入圖片描述

/**
  * 3.LinkedList的源碼分析:
  *       LinkedList list = new LinkedList(); 內部聲明瞭Node類型的first和last屬性,默認值爲null
  *       list.add(123);//將123封裝到Node中,創建了Node對象。
  *
  *       其中,Node定義爲:體現了LinkedList的雙向鏈表的說法
  *       private static class Node<E> {
  *            E item;
  *            Node<E> next;
  *            Node<E> prev;
  *
  *            Node(Node<E> prev, E element, Node<E> next) {
  *            this.item = element;
  *            this.next = next;     //next變量記錄下一個元素的位置
  *            this.prev = prev;     //prev變量記錄前一個元素的位置
  *            }
  *        }
  */

Vector的源碼分析

  • Vector 是一個古老的集合,JDK1.0就有了。大多數操作與ArrayList相同,區別之處在於Vector是線程安全的。
  • 在各種list中,最好把ArrayList作爲缺省選擇。當插入、刪除頻繁時,使用LinkedList;Vector總是比ArrayList慢,所以儘量避免使用。
/** 
  * 4.Vector的源碼分析:jdk7和jdk8中通過Vector()構造器創建對象時,底層都創建了長度爲10的數組。
  *      在擴容方面,默認擴容爲原來的數組長度的2倍。
  */    

List接口中的常用方法測試

  • List除了從Collection集合繼承的方法外,List 集合裏添加了一些根據索引來操作集合元素的方法。
    • void add(intindex, Object ele):在index位置插入ele元素
    • boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素添加進來
    • Object get(int index):獲取指定index位置的元素
    • int indexOf(Object obj):返回obj在集合中首次出現的位置
    • int lastIndexOf(Object obj):返回obj在當前集合中末次出現的位置
    • Object remove(int index):移除指定index位置的元素,並返回此元素
    • Object set(int index, Object ele):設置指定index位置的元素爲ele
    • List subList(int fromIndex, int toIndex):返回從fromIndex到toIndex位置的子集合
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 *
 * 5.List接口的常用方法
 *
 *
 * @author subei
 * @create 2020-05-12 20:54
 */
public class ListTest {
    /**
     *
     * void add(int index, Object ele):在index位置插入ele元素
     * boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素添加進來
     * Object get(int index):獲取指定index位置的元素
     * int indexOf(Object obj):返回obj在集合中首次出現的位置
     * int lastIndexOf(Object obj):返回obj在當前集合中末次出現的位置
     * Object remove(int index):移除指定index位置的元素,並返回此元素
     * Object set(int index, Object ele):設置指定index位置的元素爲ele
     * List subList(int fromIndex, int toIndex):返回從fromIndex到toIndex位置的子集合
     *
     * 總結:常用方法
     * 增:add(Object obj)
     * 刪:remove(int index) / remove(Object obj)
     * 改:set(int index, Object ele)
     * 查:get(int index)
     * 插:add(int index, Object ele)
     * 長度:size()
     * 遍歷:① Iterator迭代器方式
     *      ② 增強for循環
     *      ③ 普通的循環
     *
     */

    @Test
    public void test3(){
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(456);
        list.add("AA");

        //方式一:Iterator迭代器方式
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

        System.out.println("***************");

        //方式二:增強for循環
        for(Object obj : list){
            System.out.println(obj);
        }

        System.out.println("***************");

        //方式三:普通for循環
        for(int i = 0;i < list.size();i++){
            System.out.println(list.get(i));
        }
    }

    @Test
    public void tets2(){
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(456);
        list.add("AA");
        list.add(new Person("Tom",12));
        list.add(456);
        //int indexOf(Object obj):返回obj在集合中首次出現的位置。如果不存在,返回-1.
        int index = list.indexOf(4567);
        System.out.println(index);

        //int lastIndexOf(Object obj):返回obj在當前集合中末次出現的位置。如果不存在,返回-1.
        System.out.println(list.lastIndexOf(456));

        //Object remove(int index):移除指定index位置的元素,並返回此元素
        Object obj = list.remove(0);
        System.out.println(obj);
        System.out.println(list);

        //Object set(int index, Object ele):設置指定index位置的元素爲ele
        list.set(1,"CC");
        System.out.println(list);

        //List subList(int fromIndex, int toIndex):返回從fromIndex到toIndex位置的左閉右開區間的子集合
        List subList = list.subList(2, 4);
        System.out.println(subList);
        System.out.println(list);
    }

    @Test
    public void test(){
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(456);
        list.add("AA");
        list.add(new Person("Tom",12));
        list.add(456);

        System.out.println(list);

        //void add(int index, Object ele):在index位置插入ele元素
        list.add(1,"BB");
        System.out.println(list);

        //boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素添加進來
        List list1 = Arrays.asList(1, 2, 3);
        list.addAll(list1);
//        list.add(list1);
        System.out.println(list.size());//9

        //Object get(int index):獲取指定index位置的元素
        System.out.println(list.get(2));

    }
}

List的一個面試小題

  • 面試題1

請問ArrayList/LinkedList/Vector的異同?談談你的理解?ArrayList底層是什麼?擴容機制?Vector和ArrayList的最大區別?

   /**
     * 請問ArrayList/LinkedList/Vector的異同?談談你的理解?
     * ArrayList底層是什麼?擴容機制?Vector和ArrayList的最大區別?
     * 
     * ArrayList和LinkedList的異同二者都線程不安全,相對線程安全的Vector,執行效率高。
     * 此外,ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。
     * 對於隨機訪問get和set,ArrayList覺得優於LinkedList,因爲LinkedList要移動指針。
     * 對於新增和刪除操作add(特指插入)和remove,LinkedList比較佔優勢,因爲ArrayList要移動數據。
     * 
     * ArrayList和Vector的區別Vector和ArrayList幾乎是完全相同的,
     * 唯一的區別在於Vector是同步類(synchronized),屬於強同步類。
     * 因此開銷就比ArrayList要大,訪問要慢。正常情況下,
     * 大多數的Java程序員使用ArrayList而不是Vector,
     * 因爲同步完全可以由程序員自己來控制。Vector每次擴容請求其大小的2倍空間,
     * 而ArrayList是1.5倍。Vector還有一個子類Stack。
     */
  • 面試題2
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * @author subei
 * @create 2020-05-12 23:07
 */
public class ListEver {
    /**
     * 區分List中remove(int index)和remove(Object obj)
     */

    @Test
    public void testListRemove() {
        List list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        updateList(list);
        System.out.println(list);//
    }

    private void updateList(List list) {
//        list.remove(2);
        list.remove(new Integer(2));
    }
}

整個Java全棧系列都是筆者自己敲的筆記。寫作不易,如果可以,點個讚唄!✌

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章