Java進(jìn)階---集合

一藏研、數(shù)組和集合的比較

數(shù)組不是面向?qū)ο蟮哪叮嬖诿黠@的缺陷咐汞,集合彌補(bǔ)了數(shù)組的缺點(diǎn),比數(shù)組更靈活更實(shí)用儒鹿,而且不同的集合框架類可適用不同場(chǎng)合化撕。如:

1.數(shù)組能存放基本數(shù)據(jù)類型和對(duì)象,而集合類存放的都是對(duì)象的引用约炎,而非對(duì)象本身植阴!
2.數(shù)組容易固定無(wú)法動(dòng)態(tài)改變蟹瘾,集合類容量動(dòng)態(tài)改變。
3.數(shù)組無(wú)法判斷其中實(shí)際存有多少元素掠手,length只告訴了數(shù)組的容量憾朴,而集合的size()可以確切知道元素的個(gè)數(shù)
4.集合有多種實(shí)現(xiàn)方式和不同適用場(chǎng)合,不像數(shù)組僅采用順序表方式
5.集合以類的形式存在喷鸽,具有封裝众雷、繼承、多態(tài)等類的特性魁衙,通過(guò)簡(jiǎn)單的方法和屬性即可實(shí)現(xiàn)各種復(fù)雜操作报腔,大大提高了軟件的開發(fā)效率

二、List集合

有序列表剖淀,允許存放重復(fù)的元素;
實(shí)現(xiàn)類
ArrayList:數(shù)組實(shí)現(xiàn)纤房,查詢快纵隔,增刪慢,輕量級(jí)炮姨;(線程不安全)
LinkedList:雙向鏈表實(shí)現(xiàn)捌刮,增刪快,查詢慢 (線程不安全)
Vector:數(shù)組實(shí)現(xiàn)舒岸,重量級(jí) (線程安全绅作、使用少)

三、ArrayList

底層是Object數(shù)組蛾派,所以ArrayList具有數(shù)組的查詢速度快的優(yōu)點(diǎn)以及增刪速度慢的缺點(diǎn)俄认。
而在LinkedList的底層是一種雙向循環(huán)鏈表。在此鏈表上每一個(gè)數(shù)據(jù)節(jié)點(diǎn)都由三部分組成:前指針(指向前面的節(jié)點(diǎn)的位置)洪乍,數(shù)據(jù)眯杏,后指針(指向后面的節(jié)點(diǎn)的位置)。最后一個(gè)節(jié)點(diǎn)的后指針指向第一個(gè)節(jié)點(diǎn)的前指針壳澳,形成一個(gè)循環(huán)岂贩。
雙向循環(huán)鏈表的查詢效率低但是增刪效率高。
ArrayList數(shù)組線性表的特點(diǎn)為:類似數(shù)組的形式進(jìn)行存儲(chǔ)巷波,因此它的隨機(jī)訪問速度極快萎津。
ArrayList和LinkedList在用法上沒有區(qū)別,但是在功能上還是有區(qū)別的抹镊。

四锉屈、LinkedList

LinkedList是采用雙向循環(huán)鏈表實(shí)現(xiàn)的。
利用LinkedList實(shí)現(xiàn)棧(stack)髓考、隊(duì)列(queue)部念、雙向隊(duì)列(double-ended queue )。
它具有方法addFirst()、addLast()儡炼、getFirst()妓湘、getLast()、removeFirst()乌询、removeLast()等榜贴。
經(jīng)常用在增刪操作較多而查詢操作很少的情況下:
隊(duì)列和堆棧。
隊(duì)列:先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)妹田。
棧:后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)唬党。
注意:使用棧的時(shí)候一定不能提供方法讓不是最后一個(gè)元素的元素獲得出棧的機(jī)會(huì)。

五鬼佣、集合的遍歷--ArrayList

import java.util.*;
 
public class Test{
 public static void main(String[] args) {
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
     //第一種遍歷方法使用foreach遍歷List
     for (String str : list) {            //也可以改寫for(int i=0;i<list.size();i++)這種形式
        System.out.println(str);
     }
 
     //第二種遍歷驶拱,把鏈表變?yōu)閿?shù)組相關(guān)的內(nèi)容進(jìn)行遍歷
     String[] strArray=new String[list.size()];
     list.toArray(strArray);
     for(int i=0;i<strArray.length;i++) //這里也可以改寫為  foreach(String str:strArray)這種形式
     {
        System.out.println(strArray[i]);
     }
     
    //第三種遍歷 使用迭代器進(jìn)行相關(guān)遍歷
     
     Iterator<String> ite=list.iterator();
     while(ite.hasNext())//判斷下一個(gè)元素之后有值
     {
         System.out.println(ite.next());
     }
 }
}

三種方法都是用來(lái)遍歷ArrayList集合,第三種方法是采用迭代器的方法晶衷,該方法可以不用擔(dān)心在遍歷的過(guò)程中會(huì)超出集合的長(zhǎng)度蓝纲。

六、ArrayList注意點(diǎn)(面試可能會(huì)被問到)

a.如果在初始化ArrayList的時(shí)候沒有指定初始化長(zhǎng)度的話晌纫,默認(rèn)的長(zhǎng)度為10.

/**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
    this(10);
    }

b.ArrayList在增加新元素的時(shí)候如果超過(guò)了原始的容量的話税迷,ArrayList擴(kuò)容ensureCapacity的方案為“原始容量*3/2+1"哦。

/**
 * Increases the capacity of this <tt>ArrayList</tt> instance, if
 * necessary, to ensure that it can hold at least the number of elements
 * specified by the minimum capacity argument.
 *
 * @param   minCapacity   the desired minimum capacity
 */
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
    Object oldData[] = elementData;
    int newCapacity = (oldCapacity * 3)/2 + 1;
        if (newCapacity < minCapacity)
    newCapacity = minCapacity;
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
}
}

c.ArrayList是線程不安全的锹漱,在多線程的情況下不要使用箭养。

    如果一定在多線程使用List的,您可以使用Vector哥牍,因?yàn)閂ector和ArrayList基本一致毕泌,區(qū)別在于Vector中的絕大部分方法都
    使用了同步關(guān)鍵字修飾,這樣在多線程的情況下不會(huì)出現(xiàn)并發(fā)錯(cuò)誤哦砂心,還有就是它們的擴(kuò)容方案不同懈词,ArrayList是通過(guò)原始
    容量*3/2+1,而Vector是允許設(shè)置默認(rèn)的增長(zhǎng)長(zhǎng)度,Vector的默認(rèn)擴(kuò)容方式為原來(lái)的2倍辩诞。
    切記Vector是ArrayList的多線程的一個(gè)替代品坎弯。

d.ArrayList實(shí)現(xiàn)遍歷的幾種方法

package com.yonyou.test;
 
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 
public class Test{
public static void main(String[] args) {
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
     //第一種遍歷方法使用foreach遍歷List
     for (String str : list) {            //也可以改寫for(int i=0;i<list.size();i++)這種形式
        System.out.println(str);
    }
 
     //第二種遍歷,把鏈表變?yōu)閿?shù)組相關(guān)的內(nèi)容進(jìn)行遍歷
    String[] strArray=new String[list.size()];
    list.toArray(strArray);
    for(int i=0;i<strArray.length;i++) //這里也可以改寫為foreach(String str:strArray)這種形式
    {
        System.out.println(strArray[i]);
    }
     
    //第三種遍歷 使用迭代器進(jìn)行相關(guān)遍歷
     
     Iterator<String> ite=list.iterator();
     while(ite.hasNext())
     {
         System.out.println(ite.next());
     }
 }
}

集合數(shù)組的相關(guān)方法

       //collection接口方法
        Collection<String> t1 = new ArrayList();
        //添加元素
        t1.add("Jack");
        t1.add("Merry");
        System.out.println(t1);

        //刪除元素
        t1.remove("Jack");
        System.out.println(t1);

        //獲取元素個(gè)數(shù)
        System.out.println(t1.size());

        //判斷是否包含一個(gè)元素
        if (t1.contains("Merry")){
            System.out.println("有Merry");
        }else {
            System.out.println("沒有Merry");
        }

        //判斷是否為空
        if (t1.isEmpty()){
            System.out.println("是空的");
        }else {
            System.out.println("不是空的");
        }

        //判斷兩個(gè)集合是否相同
        Collection<String> t2 = new ArrayList();

        t2.add("Merry");
        t2.add("Jack");
        t2.add("tome");
        t2.add("bluck");

        if (t1.equals(t2)){
            System.out.println("相同");
        }else {
            System.out.println("不相同");
        }
        //集合的情空
        System.out.println("------------------");
        //集合的遍歷
        /**1.使用Iterator遍歷
         * hasNext 判斷是否有下一個(gè)對(duì)象
         * next 獲取下一個(gè)對(duì)象
         * remove 刪除當(dāng)前遍歷過(guò)后的對(duì)象
         */
      
        Iterator iterator = t2.iterator();

        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //錯(cuò)誤的方法
        while (iterator.next() != null){
            System.out.println(iterator.next());
        }

        System.out.println("------------------");
        //2.用for-each 增強(qiáng)for循環(huán)
        for (String obj: t2){
            System.out.println(obj);
        }
        

        //List接口 extends Collection
        // ArrayList  內(nèi)部是連續(xù)的內(nèi)存空間 優(yōu)點(diǎn):訪問方便get(); 缺點(diǎn):刪除译暂,添加比較難
        // LinkedArrayList 內(nèi)部使用鏈表實(shí)現(xiàn) (不一定連續(xù)) 優(yōu)點(diǎn):增加 刪除效率高 缺點(diǎn):訪問不方便
        // 集合里面只能存放對(duì)象
        // 包裝類-->Byte Char Integer Long Float Double Boolean
        // java會(huì)自動(dòng)將基本數(shù)據(jù)類型包裝為對(duì)應(yīng)的類
       
        ArrayList<Integer> score = new ArrayList<>();
        score.add(2);
        score.add(3);
        score.add(0,1);//在指定位置添加
        System.out.println(score);

        //訪問元素
        score.get(1);
        System.out.println(score);
        //修改元素 (下標(biāo)抠忘,元素)
        score.set(0,0);
        System.out.println(score);
        //刪除元素 指定下標(biāo)
        score.remove(0);
        System.out.println(score);
        //刪除指定的元素
        score.remove((Integer)2);
        System.out.println(score);
        //清空
        score.clear();
        System.out.println(score);

        ArrayList<Integer> a2 = new ArrayList<>();
        a2.add(1);
        a2.add(2);
        a2.add(3);
        a2.add(4);
        a2.add(5);
        //加入元素 把另一個(gè)集合中的元素加入
        score.addAll(a2);
        System.out.println(score);
        System.out.println("------------------");

        ArrayList<Integer> a3 = new ArrayList<>();
        a3.add(1);
        a3.add(2);

        score.retainAll(a3);//取交集
        System.out.println(score);

        System.out.println("------------------");
        ArrayList<Integer> a4 = new ArrayList<>();
        a4.add(1);
        a4.add(2);
        a4.add(3);
        a4.add(4);
        a4.add(5);

        System.out.println(a4.indexOf(1));//第一次出現(xiàn)的位置
        System.out.println(a4.lastIndexOf(1));//最后一次出現(xiàn)的位置

        System.out.println("------------------");
        //將ArrayList轉(zhuǎn)化為普通數(shù)組
       Integer[] object = new Integer[a4.size()];
       a4.toArray(object);
       System.out.println(object);

        System.out.println("------------------");
        Iterator iterator = a4.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

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

        //獲取集合某個(gè)范圍的子集合
        List<Integer> integerList = a4.subList(1,3);
        System.out.println(integerList);

        System.out.println("------------------");
       
        ArrayList<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);

        //Lambda表達(dá)式  刪除對(duì)2取余結(jié)果為0的數(shù)
        nums.removeIf( obj -> obj % 2 == 0);

        System.out.println(nums);
       
        // 1.使用方式:定義一個(gè)類來(lái)實(shí)現(xiàn)接口
        ArrayClass ac = new ArrayClass();
        int[] num = {1,2,3,4,5,6};
        PXDClass pc = new PXDClass();
        ac.test(num, pc);
     
        // 2.使用匿名類
        ArrayClass ac = new ArrayClass();
        int[] num = {1,2,3,4,5,6};
        ac.test(num, new Show() {
            @Override
            public void customShow(int element) {
                System.out.println(element);
            }
        });
        

        // 3.使用Lambda表達(dá)式
        ArrayClass ac = new ArrayClass();
        int[] num = {1,2,3,4,5,6};
        ac.test(num, (int element) -> {System.out.println(element);});
    }
}

// 閉包  把函數(shù)作為一個(gè)方法的參數(shù)
class ArrayClass{
    public void test(int[] target, Show s){
        for (int element: target){
            s.customShow(element);
        }
    }
}

// 必須是接口 這個(gè)接口里面只有一個(gè)方法
interface Show{
    void customShow(int element);
}
// 實(shí)現(xiàn)Show接口
class PXDClass implements Show{

    @Override
    public void customShow(int element) {
        System.out.println(element);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市外永,隨后出現(xiàn)的幾起案子崎脉,更是在濱河造成了極大的恐慌,老刑警劉巖伯顶,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件囚灼,死亡現(xiàn)場(chǎng)離奇詭異骆膝,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)灶体,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門阅签,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蝎抽,你說(shuō)我怎么就攤上這事政钟。” “怎么了樟结?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵养交,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我瓢宦,道長(zhǎng)碎连,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任刁笙,我火速辦了婚禮破花,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疲吸。我一直安慰自己,他們只是感情好前鹅,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布摘悴。 她就那樣靜靜地躺著,像睡著了一般舰绘。 火紅的嫁衣襯著肌膚如雪蹂喻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天捂寿,我揣著相機(jī)與錄音口四,去河邊找鬼。 笑死秦陋,一個(gè)胖子當(dāng)著我的面吹牛蔓彩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播驳概,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼赤嚼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了顺又?” 一聲冷哼從身側(cè)響起更卒,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稚照,沒想到半個(gè)月后蹂空,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俯萌,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年上枕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咐熙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡姿骏,死狀恐怖糖声,靈堂內(nèi)的尸體忽然破棺而出斟览,到底是詐尸還是另有隱情营袜,我是刑警寧澤惹苗,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布畏腕,位于F島的核電站昌腰,受9級(jí)特大地震影響击纬,放射性物質(zhì)發(fā)生泄漏虐呻。R本人自食惡果不足惜绊困,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一去团、第九天 我趴在偏房一處隱蔽的房頂上張望抡诞。 院中可真熱鬧,春花似錦土陪、人聲如沸昼汗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)顷窒。三九已至,卻和暖如春源哩,著一層夾襖步出監(jiān)牢的瞬間鞋吉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工励烦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谓着,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓坛掠,卻偏偏與公主長(zhǎng)得像赊锚,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子却音,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 原文地址 Java集合 Java集合框架:是一種工具類改抡,就像是一個(gè)容器可以存儲(chǔ)任意數(shù)量的具有共同屬性的對(duì)象。 Ja...
    gyl_coder閱讀 978評(píng)論 0 8
  • ? 在編寫java程序中系瓢,我們最常用的除了八種基本數(shù)據(jù)類型阿纤,String對(duì)象外還有一個(gè)集合類,在我們的的程序中到處...
    Java幫幫閱讀 1,410評(píng)論 0 6
  • Java集合類可用于存儲(chǔ)數(shù)量不等的對(duì)象,并可以實(shí)現(xiàn)常用的數(shù)據(jù)結(jié)構(gòu)如棧,隊(duì)列等,Java集合還可以用于保存具有映射關(guān)...
    小徐andorid閱讀 1,925評(píng)論 0 13
  • 概念 在Java中List有兩個(gè)夷陋,一個(gè)是java.util下的接口欠拾,另一個(gè)是java.awt下的類胰锌,這里只討...
    still_loving閱讀 1,304評(píng)論 0 1
  • 生活在紛繁的社會(huì),追求身心的健康藐窄、幸福不是一件易事资昧,很多時(shí)候會(huì)覺得疲憊,甚至迷茫荆忍。除了受到一些外界客觀原因的影...
    魯偉竹原愛閱讀 665評(píng)論 0 0