總結(jié):Java 集合進(jìn)階精講

集合進(jìn)階1---為集合指定初始容量

集合在Java編程中使用非常廣泛,當(dāng)容器的量變得非常大的時(shí)候碑诉,它的初始容量就會(huì)顯得很重要了.

因?yàn)閿U(kuò)容是需要消耗大量的人力物力財(cái)力的惭婿。

同樣的道理驾诈,Collection的初始容量也顯得異常重要凤瘦。所以:對(duì)于已知的情景,請(qǐng)為集合指定初始容量拂封。

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


public class ColTest {

    public static void main(String[] args) {  
        Base_User baseUser = null;  
        long begin1 = System.currentTimeMillis();  
        List<Base_User> list1 = new ArrayList<Base_User>();  
        for(int i = 0 ; i < 1000000; i++){  
            baseUser = new Base_User(i,"chenssy_"+i,i);  
            list1.add(baseUser);  
        }  
        long end1 = System.currentTimeMillis();  
        System.out.println("list1 time:" + (end1 - begin1));  
          
        long begin2 = System.currentTimeMillis();  
        List<Base_User> list2 = new ArrayList<>(1000000);  
        for(int i = 0 ; i < 1000000; i++){  
            baseUser = new Base_User(i,"chenssy_"+i,i);  
            list2.add(baseUser);  
        }  
        long end2 = System.currentTimeMillis();  
        System.out.println("list2 time:" + (end2 - begin2));  
    }  
    
}


分析:

插入1000000條數(shù)據(jù)解幽,list1沒(méi)有沒(méi)有申請(qǐng)初始化容量,而list2初始化容量1000000烘苹。運(yùn)行結(jié)果我們可以看出list2的速度是list1的兩倍左右躲株。

ArrayList的擴(kuò)容機(jī)制是比較消耗資源的。我們先看ArrayList的add方法:


public boolean add(E e) {    
        ensureCapacity(size + 1);     
        elementData[size++] = e;    
        return true;    
    }    
      
    public void ensureCapacity(int minCapacity) {    
        modCount++;         //修改計(jì)數(shù)器  
        int oldCapacity = elementData.length;      
        //當(dāng)前需要的長(zhǎng)度超過(guò)了數(shù)組長(zhǎng)度镣衡,進(jìn)行擴(kuò)容處理  
        if (minCapacity > oldCapacity) {    
            Object oldData[] = elementData;    
            //新的容量 = 舊容量 * 1.5 + 1  
            int newCapacity = (oldCapacity * 3)/2 + 1;    
                if (newCapacity < minCapacity)    
                    newCapacity = minCapacity;    
          //數(shù)組拷貝霜定,生成新的數(shù)組   
          elementData = Arrays.copyOf(elementData, newCapacity);    
        }    
    }  
    

ArrayList每次新增一個(gè)元素,就會(huì)檢測(cè)ArrayList的當(dāng)前容量是否已經(jīng)到達(dá)臨界點(diǎn)廊鸥,如果到達(dá)臨界點(diǎn)則會(huì)擴(kuò)容1.5倍望浩。

然而ArrayList的擴(kuò)容以及數(shù)組的拷貝生成新的數(shù)組是相當(dāng)耗資源的。

大數(shù)據(jù)量的前提下,指定初始化容量惰说,效率的提升和資源的利用會(huì)顯得更加具有優(yōu)勢(shì)磨德。

集合進(jìn)階2---使用entrySet遍歷Map集合KV

HashMap的遍歷有兩種常用的方法,那就是使用keyset及entryset來(lái)進(jìn)行遍歷

但兩者的遍歷速度是有差別的吆视。

第一種: entryset 效率高

Map map = new HashMap(); 
Iterator iter = map.entrySet().iterator(); 
while (iter.hasNext()) { 
    Map.Entry entry = (Map.Entry) iter.next(); 
    Object key = entry.getKey(); 
    Object val = entry.getValue(); 
} 

第二種: keySet 效率低

Map map = new HashMap(); 
Iterator iter = map.keySet().iterator(); 
while (iter.hasNext()) { 
    Object key = iter.next(); 
    Object val = map.get(key); 
} 

對(duì)于keySet其實(shí)是遍歷了2次典挑,一次是轉(zhuǎn)為iterator,一次就從hashmap中取出key所對(duì)于的value啦吧。

而entryset只是遍歷了第一次您觉,他把key和value都放到了entry中,所以就快了授滓。

集合進(jìn)階3---合理利用集合的穩(wěn)定性和有序性

合理利用集合的穩(wěn)定性(order)和有序性(sort)琳水,避免集合的無(wú)序性和不穩(wěn)定性帶來(lái)的負(fù)面影響肆糕。

  • 穩(wěn)定性指集合每次遍歷的元素次序是一定的。
  • 有序性是指遍歷的結(jié)果按某種比較規(guī)則依次排序的在孝。

ArrayList是order/unsort诚啃,HashMap是unorder/unsort,TreeSet是order/sort私沮,還可以通過(guò)TreeSet結(jié)合ArrayList對(duì)結(jié)果進(jìn)行排序绍申。

Java 常用集合的一些特征:

  • ①、LinkedList 底層是雙向鏈表顾彰。ArrayList:底層采用數(shù)組結(jié)構(gòu),里面添加的元素有序可以重復(fù)胃碾。

  • ②涨享、HashSet:底層采用哈希表算法,里面添加的元素?zé)o序不可重復(fù)仆百。

  • ③厕隧、HashMap:底層也是采用哈希表算法,但是里面添加的元素是 key-value 的形式俄周。key 不允許重復(fù)吁讨,value 可以。

如何好好利用這些集合的原理峦朗,簡(jiǎn)化我們的編程呢建丧。

1、統(tǒng)計(jì)一字符串中每個(gè)字符出現(xiàn)的次數(shù)波势?

解析:給定一串字符串翎朱,統(tǒng)計(jì)每個(gè)字符出現(xiàn)的次數(shù)。統(tǒng)計(jì)的字符是不能重復(fù)的尺铣,而出現(xiàn)的個(gè)數(shù)我們可以不用管拴曲。那么很容易聯(lián)想到 Map 的集合原理,key-value凛忿。我們將統(tǒng)計(jì)的字符放在 Map<Character,Integer>中是一種很好的實(shí)現(xiàn)方式澈灼。

HashMap

import java.util.HashMap;
import java.util.Map;


public class CnTest {

     public static Map<Character, Integer> countChar(Map<Character, Integer> map,String str){
            //將所給的字符串解析為一個(gè)字符構(gòu)造的數(shù)組
            char[] chars = str.toCharArray();
             
            for(char c : chars){
                if(map.containsKey(c)){
                    int oldCount = map.get(c);
                    map.put(c, oldCount+1);
                }else{
                    map.put(c, 1);
                }
            }
             
            return map;
        }
     
        public static void main(String[] args) {
            String str = "hello world";
            //定義一個(gè) Map 集合,用來(lái)存放統(tǒng)計(jì)的     字符--個(gè)數(shù)
            Map<Character, Integer> hashMap = new HashMap<Character, Integer>();
            System.out.println(countChar(hashMap,str));
            //{w=1, d=1,  =1, e=1, r=1, o=2, l=3, h=1}
        }
}

補(bǔ)充:這里我們用來(lái)保存統(tǒng)計(jì)字符的是 HashMap 的實(shí)現(xiàn)類店溢,這里打印出來(lái)的字符統(tǒng)計(jì)是無(wú)序的叁熔。

LinkedHashMap

根據(jù)字符串給定的順序有序的統(tǒng)計(jì)出

        public static void main(String[] args) {
            String str = "hello world";
            //定義一個(gè) Map 集合,用來(lái)存放統(tǒng)計(jì)的     字符--個(gè)數(shù)
            Map<Character, Integer> linkedHashMap = new LinkedHashMap<Character, Integer>();
            System.out.println(countChar(linkedHashMap,str));
            //{h=1, e=1, l=3, o=2,  =1, w=1, r=1, d=1}
        }
       

TreeMap

用 uicode 的編碼順序打印給定的字符串

     public static void main(String[] args) {
            String str = "hello world";
            //定義一個(gè) Map 集合床牧,用來(lái)存放統(tǒng)計(jì)的     字符--個(gè)數(shù)
            Map<Character, Integer> treeMap = new TreeMap<Character, Integer>();
            System.out.println(countChar(treeMap,str));
            //{ =1, d=1, e=1, h=1, l=3, o=2, r=1, w=1}
     }

二者疤、去掉給定數(shù)組重復(fù)的數(shù)據(jù)?

解析:將數(shù)組中的元素都放到Set叠赦,然后將 Set 集合轉(zhuǎn)變?yōu)閿?shù)組就可以了驹马。

import java.util.HashSet;
import java.util.Set;


public class CrTest {

    
    public static Integer[] clearRepeat(int [] array){
        Set<Integer> set = new HashSet<Integer>();
        for(int i : array){
            set.add(i);
        }
        Integer[] newArray = set.toArray(new Integer[set.size()]);
        return newArray;
    }
     
     
    public static void main(String[] args) {
        //創(chuàng)建一個(gè)數(shù)組革砸,可以看出 2和4 是重復(fù)的
        int [] array = {1,2,3,4,2,2,3,4};
        Integer[] newArray = clearRepeat(array);
        for(Integer i : newArray){
            System.out.println(i);
        }
        //1 2 3 4
         
    }
}

同理我們可以改變 Set 集合的實(shí)現(xiàn)類,hashSet 是無(wú)序的糯累,我們可以會(huì)用** LinkedHashSet** 保證既定順序算利;TreeSet 保證自然順序

over

by:一只阿木木

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市泳姐,隨后出現(xiàn)的幾起案子效拭,更是在濱河造成了極大的恐慌,老刑警劉巖胖秒,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缎患,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡阎肝,警方通過(guò)查閱死者的電腦和手機(jī)挤渔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)风题,“玉大人判导,你說(shuō)我怎么就攤上這事∨婀瑁” “怎么了眼刃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)摇肌。 經(jīng)常有香客問(wèn)我擂红,道長(zhǎng),這世上最難降的妖魔是什么围小? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任篮条,我火速辦了婚禮,結(jié)果婚禮上吩抓,老公的妹妹穿的比我還像新娘涉茧。我一直安慰自己,他們只是感情好疹娶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布伴栓。 她就那樣靜靜地躺著,像睡著了一般雨饺。 火紅的嫁衣襯著肌膚如雪钳垮。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,258評(píng)論 1 300
  • 那天额港,我揣著相機(jī)與錄音饺窿,去河邊找鬼。 笑死移斩,一個(gè)胖子當(dāng)著我的面吹牛肚医,可吹牛的內(nèi)容都是我干的绢馍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼肠套,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼舰涌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起你稚,我...
    開(kāi)封第一講書(shū)人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瓷耙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后刁赖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體搁痛,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年宇弛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鸡典。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涯肩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出巢钓,到底是詐尸還是另有隱情病苗,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布症汹,位于F島的核電站硫朦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏背镇。R本人自食惡果不足惜咬展,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瞒斩。 院中可真熱鬧破婆,春花似錦、人聲如沸胸囱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)烹笔。三九已至裳扯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谤职,已是汗流浹背饰豺。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留允蜈,地道東北人冤吨。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓蒿柳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锅很。 傳聞我的和親對(duì)象是個(gè)殘疾皇子其馏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

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

  • 一叛复、集合入門總結(jié) 集合框架: Java中的集合框架大類可分為Collection和Map;兩者的區(qū)別: 1扔仓、Col...
    程序員歐陽(yáng)閱讀 11,558評(píng)論 2 61
  • Java集合框架 Java中封裝了許多常用的數(shù)據(jù)結(jié)構(gòu)褐奥,稱為集合框架,可以有效組織數(shù)據(jù)翘簇,提高程序性能撬码。最初Java只...
    Steven1997閱讀 933評(píng)論 0 2
  • 在一個(gè)方法內(nèi)部定義的變量都存儲(chǔ)在棧中,當(dāng)這個(gè)函數(shù)運(yùn)行結(jié)束后版保,其對(duì)應(yīng)的棧就會(huì)被回收呜笑,此時(shí),在其方法體中定義的變量將不...
    Y了個(gè)J閱讀 4,417評(píng)論 1 14
  • 夏天彻犁,除了熱叫胁,還是熱,一不小心中暑汞幢、突發(fā)疾病等一系列可能驼鹅,很多高血壓患者的血壓在夏季氣溫升高后很可能升高。高血壓早...
    lilitaisi閱讀 842評(píng)論 0 0
  • 回來(lái)兩天了森篷,花在吃飯上的錢現(xiàn)在還沒(méi)有多少输钩! 全是他們拿的錢,自己什么都沒(méi)出仲智。還是不錯(cuò)的买乃。 晚上,好哥請(qǐng)我吃了頓雞公...
    xiao錢錢閱讀 105評(píng)論 0 0