Java基礎(chǔ)——集合

首先呢,給大家講一下集合的由來(lái):java的思想是面向?qū)ο笏枷?,如果想統(tǒng)一的管理所有的對(duì)象,就涉及到用容器來(lái)儲(chǔ)存對(duì)象,而對(duì)象數(shù)組是可以存儲(chǔ)對(duì)象的,但是數(shù)組有一個(gè)缺點(diǎn)就是長(zhǎng)度固定,為了突破這一限制 ,集合就應(yīng)運(yùn)而生了。

數(shù)組和集合的優(yōu)缺點(diǎn)

長(zhǎng)度:數(shù)組固定,集合可變;
內(nèi)容:集合只能存儲(chǔ)引用類型,數(shù)組可以存儲(chǔ)基本類型和引用類型。

集合體系

單列集合頂層接口
Collection
    |-List有序(存入和取出順序相同) 存入的元素可以重復(fù) 有索引 可以通過(guò)索引來(lái)操作元素
        |-ArrayList 數(shù)組結(jié)構(gòu)
        |-LinkedList    鏈表結(jié)構(gòu)
        |-Vector    數(shù)組結(jié)構(gòu)
    |-Set 無(wú)序(存入和取出順序不同) 存入的元素不可以重復(fù)
        |-HashSet    哈希算法
        |-TreeSet   二叉樹(shù)算法
雙列集合
Map
    |-HashMap
    |-TreeMap
Collection

常用方法

boolean add(E e):向集合中添加元素e,添加成功返回true,添加失敗返回false(List集合永遠(yuǎn)添加成功 Set集合就有可能添加失敗因?yàn)镾et集合會(huì)去掉重復(fù)元素)
boolean remove(Object o):刪除集合中的元素o,刪除成功則true,刪除失敗則false
void clear():清空集合里面的元素
boolean contains(Object o):集合是否包含元素o,如果包含返回true,如果不包含返回false
boolean isEmpty():判斷集合是否為空
int size():集合的長(zhǎng)度
集合的長(zhǎng)度:c.size();
字符串長(zhǎng)度:s.length();
數(shù)組的長(zhǎng)度:arr.length;

代碼演示:

public static void main(String[] args) {
    Collection c = new ArrayList();     //父類引用指向子類對(duì)象
    boolean b1 = c.add("abc");          //添加一個(gè)字符串
    boolean b2 = c.add(true);           //自動(dòng)裝箱new Boolean(true);
    boolean b3 = c.add(100);            //自動(dòng)裝箱new Integer(100);
    boolean b4 = c.add(new Student("張三",23));   //添加一個(gè)自定義對(duì)象 
    boolean b5 = c.add("abc");          //添加一個(gè)重復(fù)的字符串

    System.out.println(b1);     //true
    System.out.println(b2);     //true
    System.out.println(b3);     //true
    System.out.println(b4);     //true
    System.out.println(b5);     //true

    System.out.println(c);//[abc, true, 100, Student [name=張三, age=23], abc]  
    //ArrayList的父類重寫(xiě)了Object的toString()

    Collection c1 = new ArrayList();        //父類引用指向子類對(duì)象        
    c1.add("a");
    c1.add("b");
    c1.add("c");
    c1.add("d");

    c1.remove("b");                 //刪除指定元素
    System.out.println(c1);             //[a, c, d]

    System.out.println(c1.contains("b"));       //false  判斷是否包含
    System.out.println(c1.contains("c"));       //true  判斷是否包含

    System.out.println(c1.size());          //3  長(zhǎng)度為3 

    System.out.println(c1.isEmpty());       //false  不為空

    c1.clear();                 //清空集合                                      //清空集合
    System.out.println(c1);             //[]
}

Object[] toArray():集合轉(zhuǎn)數(shù)組 (可以用來(lái)遍歷)

代碼演示:

public static void main(String[] args) {
    Collection c = new ArrayList();
    c.add(new Student("張三", 23));       //自動(dòng)類型提升:Object obj = new Student("張三",23);
    c.add(new Student("李四", 24));
    c.add(new Student("王五", 25));
    c.add(new Student("趙六", 26));

    Object[] arr = c.toArray();     //將集合轉(zhuǎn)換成數(shù)組
    for (int i = 0; i < arr.length; i++) {
        Student s = (Student)arr[i];    //向下轉(zhuǎn)型
        System.out.println(s.getName() + "..." + s.getAge());
    }
}

不常用的帶All的方法

boolean addAll(Collection c):添加 c里面的所有元素
boolean removeAll(Collection c):刪除交集
boolean containsAll(Collection c):是否全部包含
boolean retainAll(Collection<?> c):取交集

迭代器 Iterator

迭代器的原理

Iterator是個(gè)接口,是通過(guò)集合里面的內(nèi)部類實(shí)現(xiàn)的。迭代器是對(duì)集合進(jìn)行遍歷,而每一個(gè)集合內(nèi)部的存儲(chǔ)結(jié)構(gòu)都是不同的,所以每一個(gè)集合存和取都是不一樣,那么就需要在每一個(gè)類中定義hasNext()和next()方法。這樣做是可以的,但是會(huì)讓整個(gè)集合體系過(guò)于臃腫,迭代器是將這樣的方法向上抽取出接口,然后在每個(gè)類的內(nèi)部定義自己迭代方式,這樣做的好處有二:第一、規(guī)定了整個(gè)集合體系的遍歷方式都是hasNext()和next()方法;第二、代碼有底層內(nèi)部實(shí)現(xiàn),使用者不用管怎么實(shí)現(xiàn)的,會(huì)用即可。

代碼演示:

public static void main(String[] args) {
    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));
        
    //獲取迭代器
    Iterator it = c.iterator();
    while(it.hasNext()) {
        System.out.println(((Student)it.next()).getName()+"  "+
                    ((Student)it.next()).getAge());//如果這樣寫(xiě)的話  打印結(jié)果為  zhangsan  14 并且報(bào)錯(cuò)java.util.NoSuchElementException 因?yàn)閚ext()方法調(diào)用一次,指針就往后走一次
        
        Student s = (Student)it.next(); //所以一般while循環(huán)里面 就出現(xiàn)一次next(),如果想使用多次 請(qǐng)用一個(gè)變量接受next()方法的返回值 
        System.out.println(s.getName()+"  "+s.getAge());
    }
}
List接口

List的特有方法

void add(int index,E element);在指定的index位置插入element元素
E remove(int index);刪除index位置上的元素
E get(int index);獲取指定index位置上的元素??梢杂脕?lái)遍歷List集合,而且這種遍歷方式是List特有的遍歷方式
E set(int index,E element);把集合中index位置上的元素用element元素替換

concurrentModificationException:并發(fā)修改異常

原因:在用迭代器遍歷集合的時(shí)候,我們通過(guò)集合改變了元素,而迭代器是通過(guò)集合得到的,集合發(fā)生了改變,而迭代器還是通過(guò)原來(lái)的集合得到的,所以產(chǎn)生了并發(fā)修改異常。
解決:

  1. 通過(guò)迭代器遍歷集合的時(shí)候,我們通過(guò)迭代器來(lái)改變集合元素,而這時(shí)候原來(lái)Iterator沒(méi)有添加元素的方法,所以就用ListIterator,因?yàn)長(zhǎng)istIterator里面有add方法
  2. 通過(guò)普通for循環(huán)來(lái)遍歷集合的時(shí)候,用集合來(lái)改變?cè)?/li>

代碼演示:

public static void main(String[] args) {
    List list = new ArrayList();
    list.add("a");              //Object obj = new String();
    list.add("b");
    list.add("world");
    list.add("c");
    list.add("d");
    list.add("e");

    //報(bào)并發(fā)修改異常原因:
    Iterator it = list.iterator();  //獲取迭代器
    while(it.hasNext()) {           //判斷集合中是否有元素
        String str = (String)it.next(); //向下轉(zhuǎn)型
        if("world".equals(str)) {
            //遍歷的同時(shí)在用集合調(diào)用add方法增加元素,并發(fā)修改ConcurrentModificationException
            list.add("javaee"); 
        }
    }

    //解決方案一
    ListIterator lit = list.listIterator();//獲取迭代器(List集合特有的)可以通過(guò)hasPrevious()和previous()來(lái)往前遍歷
    while(lit.hasNext()) {
        String str = (String)lit.next();//向下轉(zhuǎn)型
        if("world".equals(str)) {
            lit.add("javaee");  //遍歷的同時(shí)用迭代器調(diào)用add方法添加元素就沒(méi)問(wèn)題
        }
    }

    //解決方案二
    for (int i = 0; i < list.size(); i++) { //通過(guò)普通for循環(huán)來(lái)遍歷集合的時(shí)候,用集合來(lái)改變?cè)?        String str = (String)list.get(i);
        if("world".equals(str)){
            list.add("javaee");
        }
    }

    System.out.println(list);
}

ArrayList

基本上都是從List實(shí)現(xiàn)的方法,因此沒(méi)有特有的方法。
案例:ArrayList去除集合中字符串的重復(fù)值(字符串的內(nèi)容相同)

public static void main(String[] args) {
    ArrayList list = new ArrayList();
    list.add("a");
    list.add("a");
    list.add("b");
    list.add("b");
    list.add("c");
    list.add("c");
    list.add("c");
    list.add("c");
        
    ArrayList newList = getSingle(list);
    System.out.println(newList);
}
/*
* 分析:
* 1,創(chuàng)建新集合
* 2,根據(jù)傳入的集合(老集合)獲取迭代器
* 3,遍歷老集合
* 4,通過(guò)新集合判斷是否包含老集合中的元素,如果包含就不添加,如果不包含就添加
*/
public static ArrayList getSingle(ArrayList list) {
    ArrayList newList = new ArrayList<>();      //1,創(chuàng)建新集合
    Iterator it = list.iterator();          //2,根據(jù)傳入的集合(老集合)獲取迭代器

    while(it.hasNext()) {               //3,遍歷老集合
        Object obj = it.next();         //記錄住每一個(gè)元素
        if(!newList.contains(obj)) {    //如果新集合中不包含老集合中的元素
            newList.add(obj);           //將該元素添加
        }
    }
    return newList;
}

LinkedList

public void addFirst(E e)將指定元素插入此列表的開(kāi)頭。
public void addLast(E e)將指定元素添加到此列表的結(jié)尾。
public E removeFirst()移除并返回此列表的第一個(gè)元素。
public E removeLast()移除并返回此列表的最后一個(gè)元素。
public E getFirst()返回此列表的第一個(gè)元素。
public E getLast()返回此列表的最后一個(gè)元素。

代碼演示:

public static void main(String[] args) {
    LinkedList list = new LinkedList();
    list.addFirst("a");
    list.addFirst("b");
    list.addFirst("c");
    list.addFirst("d");
    list.addLast("e");
    System.out.println(list.getFirst());    //d
    System.out.println(list.getLast()); //e
    System.out.println(list.removeFirst()); //d
    System.out.println(list.removeLast());  //e
    System.out.println(list);       //[c, b, a]
}

棧和隊(duì)列:
棧: 先進(jìn)后出
隊(duì)列: 先進(jìn)先出

Vector

jdk1.0出現(xiàn)1.2并入到List體系,后來(lái)被ArrayList替代,所以了解即可。

附:
數(shù)組結(jié)構(gòu):查詢快 增刪慢
鏈表結(jié)構(gòu):查詢慢 增刪快

List的三個(gè)兒子的特點(diǎn)
ArrayList:查詢快 增刪慢 不安全 效率高
LinkedList:查詢慢 增刪快 不安全 效率高
Vector:查詢快 增刪慢 安全 效率低

好了集合部分就先說(shuō)到這了,想了解更多學(xué)習(xí)知識(shí),請(qǐng)關(guān)注微信公眾號(hào)“阿Q說(shuō)”,獲取更多學(xué)習(xí)資料吧!你也可以后臺(tái)留言說(shuō)出你的疑惑,阿Q將會(huì)在后期的文章中為你解答。每天學(xué)習(xí)一點(diǎn)點(diǎn),每天進(jìn)步一點(diǎn)點(diǎn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 四、集合框架 1:String類:字符串(重點(diǎn)) (1)多個(gè)字符組成的一個(gè)序列,叫字符串。生活中很多數(shù)據(jù)的描述都采...
    佘大將軍閱讀 879評(píng)論 0 2
  • 集合類簡(jiǎn)介 為什么出現(xiàn)集合類?面向?qū)ο笳Z(yǔ)言對(duì)事物的體現(xiàn)都是以對(duì)象的形式,所以為了方便對(duì)多個(gè)對(duì)象的操作,就要對(duì)對(duì)象進(jìn)...
    阿敏其人閱讀 1,562評(píng)論 0 7
  • 一、基礎(chǔ)知識(shí):1、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機(jī)...
    殺小賊閱讀 2,575評(píng)論 0 4
  • Java類中集合的關(guān)系圖 1. 集合類概述 1.1 為什么出現(xiàn)集合類? 面向?qū)ο笳Z(yǔ)言對(duì)事物的體現(xiàn)都是以對(duì)象的形式,...
    JackChen1024閱讀 477評(píng)論 0 4
  • 集合框架、generic泛型、List、Set、Map、Collections類 集合框架 數(shù)組和集合的區(qū)別:1....
    xiaohan_zhang閱讀 315評(píng)論 0 0

友情鏈接更多精彩內(nèi)容