Day15 --框架集合 Collection集合 和 List 集合
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                Day15  --框架集合 Collection集合 和 List 集合
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
                                
                            
                            
                            a.
????對(duì)象數(shù)組 --自定義對(duì)象類
????????概述
????????????* 創(chuàng)建一個(gè)自定義類用于存儲(chǔ)學(xué)生信息,并且獲取到每個(gè)學(xué)生信息 。
????????使用
????????????Student[] s = new Student[5];????//創(chuàng)建student類,用于存儲(chǔ)數(shù)組對(duì)象。
????????????s[0] = new Student("hah", 2);????//第一個(gè)Student數(shù)組的元素,且每個(gè)地址值有所不同
????????????s[1] = new Student("fas", 4);????// 數(shù)組中存儲(chǔ)的元素記錄的都是地址值,通過每個(gè)地址值找到一個(gè)個(gè)的new的元素對(duì)象。
????????????s[2] = new Student("fasd",34);
????????????s[3] = new Student("we", 43);
????????????s[4] = new Student("ad", 23);
????????????for (int i = 0; i < s.length; i++) {
????????????????System.out.println(s[i]);
????????????}?
?????????????????????
????????注意
????????????* 數(shù)組和集合存儲(chǔ) 引用數(shù)據(jù)類型 的時(shí)候,存儲(chǔ)都是地址值,且每個(gè)地址值都有所不同,通過地址值來查找每個(gè)元素對(duì)象。
????????????* 自定義對(duì)象數(shù)組中 存儲(chǔ)的元素記錄的其實(shí)都是地址值,即每個(gè)元素對(duì)象的地址值。 通過每個(gè)索引地址值找到每個(gè) new的元素對(duì)象。
 
b.
????集合
????????--由來
????????????* 前提:數(shù)組和集合都是容器。
????????????* 因?yàn)閿?shù)組的長(zhǎng)度是固定的,當(dāng)添加的元素超過數(shù)組的長(zhǎng)度需要對(duì)數(shù)組進(jìn)行重新定義,這樣太麻煩。 所以Java在jdk1.2的時(shí)候?yàn)槲覀兲峁┝思项悺<?#xff1a;用于存儲(chǔ)任意對(duì)象,而且長(zhǎng)度可以改變,是隨著元素的增加而增加,隨著元素的減少而減少的,即隨著元素個(gè)數(shù)的變化而變化。
????????????
????????--概述
????????????* 數(shù)組和集合都是容器。
????????????* 集合于jdk1.2時(shí)被提出,長(zhǎng)度可改變,是隨著元素個(gè)數(shù)的變化而變化。
????????數(shù)組和集合區(qū)別
????????????* 可以從兩方面來說:A存儲(chǔ)的類型 和 B存儲(chǔ)的長(zhǎng)度:
????????????* 區(qū)別:
????????????????區(qū)別1:
???????????????????* 數(shù)組既可以存儲(chǔ)基本數(shù)據(jù)類型,也可存儲(chǔ)引用數(shù)據(jù)類型。基本數(shù)據(jù)類型存儲(chǔ)的是值,而引用數(shù)據(jù)類型存儲(chǔ)的是地址值。
???????????????????* 集合只能存儲(chǔ)引用數(shù)據(jù)類型(對(duì)象)集合也可以存儲(chǔ)基本數(shù)據(jù)類型,但存儲(chǔ)的時(shí)候會(huì)自動(dòng)裝箱變成對(duì)象,即int類型的100,存儲(chǔ)到集合中就變成了new Integer(100)。
????????????????區(qū)別2:
????????????????????* 數(shù)組的長(zhǎng)度是固定的,不可自動(dòng)增加。
????????????????????* 集合的長(zhǎng)度是可變的,是根據(jù)元素個(gè)數(shù)的變化而變化。
????????????????????
????????--數(shù)組和集合什么時(shí)候使用
????????????* 如果元素個(gè)數(shù)固定,就用數(shù)組。
????????????* 如果元素個(gè)數(shù)未知,不是固定,就用集合。????--部分集合底層代碼還是用數(shù)組來實(shí)現(xiàn)的,如果超出了數(shù)組的范圍,就創(chuàng)建一個(gè) 大于前者的1.5倍長(zhǎng)度的數(shù)組。增長(zhǎng)后,將原數(shù)組變成垃圾,以此類推。
????
????
????--集合繼承體系關(guān)系圖????????
??????????????-Collection --單列集合根接口
??????????????????* List -存取有序,和數(shù)組相同。有索引,可存儲(chǔ)重復(fù)元素。
??????????????????????* ArrayList???底層 數(shù)組實(shí)現(xiàn)。?
??????????????????????* LinkedList??底層 鏈表實(shí)現(xiàn)。?
??????????????????????* Vector(jdk1.0) 底層 數(shù)組實(shí)現(xiàn)。 --已被ArrayList替代。 之所以和集合命名規(guī)則不同,是集合體系是jdk1.2時(shí)候被提出,而jdk1.0的時(shí)候已經(jīng)有了Vector,因?yàn)閂ector中的功能和集合一樣,所以讓Vector也實(shí)現(xiàn)了List接口并且并入到了集合體系中。
??????????????????* Set -存取無序,無索引,不可存儲(chǔ)重復(fù)元素。
??????????????????????* HashSet????????底層 Hash算法。????元素?zé)o序。
??????????????????????* LinkedHashSet 底層 鏈表結(jié)構(gòu),是set集合中唯一一個(gè)怎么存怎么取的集合,又因?yàn)槭荋ashSet的子類,所以同樣保證了元素的唯一性。
??????????????????????* TreeSet????????底層 二叉樹算法。 元素可以進(jìn)行排序。
??????????????????????
??????????????-Map????--雙列集合根接口
???????????????????* HashMap 底層 哈希算法。 保證鍵的唯一性。
???????????????????* TreeMap 底層 二叉樹。 鍵可以排序。
??????????????????????
 
 
c.
????Collection
????????--概述
????????????* Collection是所有 單列集合 的根類接口。
????????????* Map是所有 雙列集合 的根接口。
????????????* 集合是jdk1.2的時(shí)候提出。
????????????* 集合的命名都有一定的規(guī)范:底層是怎么實(shí)現(xiàn)的,前者單詞就是什么,后者是哪個(gè)繼承體系下的。后者單詞就是什么。
????????????如:
????????????????ArrayList 底層數(shù)組實(shí)現(xiàn),屬于List集合下。
????????????????LinkedList 底層鏈表實(shí)現(xiàn),所以List集合下。
????--體系結(jié)構(gòu)圖:????????
????????Collection(單列集合根接口)
????????????* List(有序,有索引,可重復(fù)元素)
????????????????* ArrayList??數(shù)組實(shí)現(xiàn)。存取有序,和數(shù)組一樣。有索引,可存儲(chǔ)重復(fù)元素。
????????????????* LinkedList 鏈表實(shí)現(xiàn)。
????????????????* Vector(jdk1.0) 數(shù)組實(shí)現(xiàn)。之所以和集合命名規(guī)則不同,是因?yàn)樵趈dk1.0時(shí)候出現(xiàn),而集合體系是jdk1.2時(shí)候出現(xiàn),已被ArrayList替代。
????????????* Set (無序,無索引,不可重復(fù)元素)
????????????????* HastSet 哈希算法。
????????????????* TreeSet 二叉樹算法。
????????????????
????????注意:List是一個(gè)不可插隊(duì)的插入對(duì)象。
????????
 
 
d.
????Collection集合的基本功能
????????概述
??????????* util包下,用時(shí)需導(dǎo)包。
??????????* Collection 是接口,用時(shí)只能:父類引用指向子類對(duì)象,即:????Collection c = new ArrayList();
??????????* Collection 單列集合 中的根接口。
??????????* Collection 表示一組對(duì)象,這些對(duì)象也稱為 collection 的元素。一些 collection 允許有重復(fù)的元素(list),而另一些則不允許(set)。一些collection 是有序的(list),而另一些則是無序的(set)。
??????????* JDK不提供此接口的任何直接 實(shí)現(xiàn):它提供更具體的子接口(如 Set 和 List)實(shí)現(xiàn)。
????????常用方法
?????????* boolean add(Object obj);?????????添加對(duì)象 可添加任意對(duì)象。?????
?????????*?????????????????????????????????????????????結(jié)果Boolean永遠(yuǎn)都是true。那什么時(shí)候是false? 只有當(dāng)set集合存儲(chǔ)重復(fù)元素的時(shí)候,返回false。
?????????*?????????????????????????????????????????????所以一般我們不用返回值類型,自己將對(duì)象添加到集合中即可。即:c.add("sfa");
?????????*?
?????????* boolean remove(Object obj);?????刪除對(duì)象 可刪除任意對(duì)象。可以是基本數(shù)據(jù)類型,到時(shí)候會(huì)自動(dòng)裝箱成對(duì)象。
?????????* void clear();?????????????????????清空集合元素
?????????* boolean contains(Object o);????????判斷是否包含指定元素
?????????* boolean isEmpty();????????????????判斷集合是否為空,為空就返回true,否則為false。
?????????* int size();????????????????????????獲取集合中的元素個(gè)數(shù)
?????????
????注意:1)add如果是List集合,就一直返回true,因?yàn)閘ist集合中是可以存儲(chǔ)重復(fù)元素的。
?????????????如果是set集合用add存儲(chǔ)重復(fù)元素,就會(huì)返回false。
?????????2)ArrayList的父類的父類重寫了toString方法,所以在打印對(duì)象的引用時(shí)輸出的結(jié)果不是Object的??toString 的結(jié)果,而是集合特有的:[元素]的形式。
 
?????????collectionXxx.java使用了未經(jīng)檢查或不安全的操作.
?????????注意:要了解詳細(xì)信息,請(qǐng)使用 -Xlint:unchecked重新編譯.
????????????java編譯器認(rèn)為該程序存在安全隱患
????????????溫馨提示:這不是編譯失敗,所以先不用理會(huì),等 學(xué)了泛型你就知道了
 
 
 
 
????toArray() 集合的遍歷之集合轉(zhuǎn)數(shù)組遍歷的功能
????????集合遍歷
????????????* 就是依次獲取集合中的每個(gè)元素。
????????????* 集合轉(zhuǎn)數(shù)組,就可以實(shí)現(xiàn)對(duì)集合的遍歷。
????????????* Object[] toArray(); 集合轉(zhuǎn)數(shù)組的方式就可以遍歷集合中的每個(gè)元素。
????????代碼
????????????//自定義 Bean對(duì)象 的遍歷方式。
????????????????????Collection c2 = new ArrayList(); //創(chuàng)建單列集合對(duì)象。
????????????????????c2.add(new Student("哈哈",23));??//等同于 Object o = new Student("哈哈",23);
????????????????????c2.add(new Student("嘻嘻",25));
????????????????????c2.add(new Student("么么",332));
????????????????????c2.add(new Student("啦啦",645));
????????????????????
????????????????????Object[] array2 = c2.toArray();
????????????????????for (int i = 0; i < array2.length; i++) {
?????????????????????????System.out.println(array2[i]); //獲取集合中所有的元素對(duì)象。
?????????????????????????
????????????//?????????????如果想獲取每個(gè)元素對(duì)象中的Name 或 age,就要向下轉(zhuǎn)型,即Object轉(zhuǎn)成Student對(duì)象。現(xiàn)在的array2[i] 就是Ojbect對(duì)象。
????????????//????????????(看左邊的類型,如果左邊是Object對(duì)象 就是向上轉(zhuǎn)型,如果左邊是Student對(duì)象,就是向下轉(zhuǎn)型)
?????????????????????????Student st =(Student)array2[i];????//向下轉(zhuǎn)型。將Object的array2轉(zhuǎn)成Student。
?????????????????????????System.out.println("姓名:"+st.getName()+"??年齡:"+st.getAge());
????????????????????}
 
 
????Collection集合中方法帶有All后綴的功能
????????????* boolean addAll(Collection c);????添加集合。
????????????????* 如:
????????????????????* c1集合有對(duì)象:abcd??c2集合有對(duì)象:ef
????????????????????* c1.addAll(c2); 將c2集合中的每個(gè)對(duì)象添加c1中,結(jié)果為:[a,b,c,d,e,f]
????????????????????* c1.add(c2); 將c2看做是一個(gè)整個(gè)對(duì)象添加到c1中,結(jié)果為:[a,b,c,d,[e,f]]
????????????????
????????????* boolean removeAll(Collection c);??刪除集合或刪除集合的元素,刪除的是兩個(gè)集合的交集為true,如果刪除的是兩個(gè)集合沒有的交集,就是false。
????????????* boolean containsAll(Collection c); 是否一個(gè)集合包含另一個(gè)集合的所有元素。如果全包含就為true,否之為false。
????????????* boolean retainAll(Collection c);??取出兩個(gè)集合之間的交集。
????????????????* 注意:如果調(diào)用的集合改變就返回true, 如果調(diào)用的集合沒有改變就返回false。
?????????????????????如:
?????????????????????????1) c1集合有:abcd?????c2集合有 ab????c1.retainAll(c2);??取交集c1結(jié)果為:ab,c1改變了,所以返回true。?????
?????????????????????????2) c1集合有:abcd?????c2集合有 z?????c1.retainAll(c2);??取交集c1結(jié)果為:[], 但c1還是改變,所以也返回true。
?????????????????????????3) c1集合有:abcd?????c2集合有 abcdefg?????c1.retainAll(c2);???取交集c1結(jié)果為:abcd,c1沒有改變,所以為false。
?????????????????????這就是retainAll的特殊之處,主要是 前者跟后者比較,前者的結(jié)果是否改變,如果改變就是true,如果沒變就是false。?????
 
 
????
????Collection集合的Iterator迭代器的遍歷方式
????????????概述
????????????????* 集合用于存儲(chǔ)元素,存儲(chǔ)的元素如果需要查看,就要使用迭代器的方式。
????????????使用
????????????????* 使用 Iterator 的方式來迭代。
????????????????* 關(guān)鍵方法:
????????????????????* hasNext(); 判斷是否還有下一個(gè)元素,如果有就返回true。
????????????????????* next(); 返回迭代的下一個(gè)元素,即將集合中的元素取出。
????????????????????????* next具有將指針向下移一位的功能。
 
 
????Collection存儲(chǔ)自定義對(duì)象并遍歷
????????????Collection c = new ArrayList(); // 創(chuàng)建集合對(duì)象。父類引用指向子類對(duì)象
????????????c.add(new Student("趙白石",43));??//等等于: Object??obj = new Student("趙白石",43); 即父類引用指向子類對(duì)象,obj不能使用子類特有的屬性和行為,即使用只能靠向下轉(zhuǎn)型的方式才能夠子類特有的屬性和行為。
????????????c.add(new Student("沈星移",33));
????????????c.add(new Student("周瑩",40));
????????????c.add(new Student("吳聘",42));
????????????
//????????方式一:while來做
????????/*????Iterator it = c.iterator();
????????????while(it.hasNext()){
????????????????Student st = (Student)it.next(); //向下強(qiáng)轉(zhuǎn)。 將it.next的Iterator的對(duì)象向下強(qiáng)轉(zhuǎn)成Student對(duì)象。只有向下轉(zhuǎn)型,才能使用子類特有的屬性和行為。
????????????????String name = st.getName();?
????????????????int age = st.getAge();
????????????????System.out.println("姓名:"+name+".....年齡:"+age);
????????????}*/
//【注意:向下轉(zhuǎn)型,才能使用子類特有的屬性和行為】
????????????
//????????方式二:for循環(huán)來做
????????for (Iterator it = c.iterator(); it.hasNext();) {
????????????????Student s = (Student)it.next();??//向下強(qiáng)轉(zhuǎn)。將it.next的Iterator的對(duì)象向下強(qiáng)轉(zhuǎn)成Student對(duì)象。這樣就能獲取子類特有的屬性和行為。
????????????????System.out.println(s.getName()+"..."+s.getAge());
????????}
????}
 
????--迭代器的原理及源碼解析
?????????原理????
?????????????迭代器是對(duì)集合進(jìn)行遍歷的,而每個(gè)集合內(nèi)部的存儲(chǔ)結(jié)構(gòu)都是不同,所以每個(gè)集合的存和取的方式也都不同的。那么就需要在每一個(gè)類中都去定義hasNext()方法 和 next()方法,這樣做可以方便的判斷是否有下一個(gè)元素和返回集合中的當(dāng)前元素。但是這樣整個(gè)集合體系看起來就會(huì)過于臃腫。所以就將迭代器向上抽取出一個(gè)接口,然后在每個(gè)類的內(nèi)部去定義自己的迭代方式。 這樣做的好處有二:
?????????????第一:規(guī)定了整個(gè)集合體系的遍歷方式通過通過hasNext()和next()方法來實(shí)現(xiàn)的。第二:代碼由底層內(nèi)部實(shí)現(xiàn),使用者無需關(guān)心怎么實(shí)現(xiàn)的,會(huì)用即可。
 
????????迭代器的原理:
????????迭代器是用來遍歷集合。因?yàn)榧系牡讓訑?shù)據(jù)結(jié)構(gòu)不同,就導(dǎo)致集合存取元素的方式不同,如果每個(gè)集合類都定義自己的存取方式,這樣做是可以的,但是會(huì)讓整個(gè)繼承體系很冗余,臃腫。所以我們經(jīng)過不斷的向上抽取,最終定義成了接口。
????????這樣做的好處有兩個(gè):
????????????A:更規(guī)范。
????????????B:我們不用管底層是怎么實(shí)現(xiàn),只要會(huì)用就可以了。
????????
????????
????????迭代器源碼解析
??????????????* 1,在eclipse中ctrl + shift + t找到ArrayList類
??????????????* 2,ctrl+o查找iterator()方法
??????????????* 3,查看返回值類型是new Itr(),說明Itr這個(gè)類實(shí)現(xiàn)Iterator接口
??????????????* 4,查找Itr這個(gè)內(nèi)部類,發(fā)現(xiàn)重寫了Iterator中的所有抽象方法?
????????????
????????Iterator iterator(); 該對(duì)象必須依賴具體的集合容器,因?yàn)槊總€(gè)集合容器的內(nèi)部數(shù)據(jù)結(jié)構(gòu)不同,所以該迭代器對(duì)象是在集合容器中進(jìn)行內(nèi)部實(shí)現(xiàn)的,也就是說iterator()方法在每個(gè)集合容器中的實(shí)現(xiàn)方式時(shí)不同的。
????????對(duì)于調(diào)用者來說,具體的實(shí)現(xiàn)過程無需知道,只要通過該集合容器獲取到該實(shí)現(xiàn)的迭代器對(duì)象即可,也就是iterator方法。
????????Iterator接口就是對(duì)所有單列集合根接口Collection容器進(jìn)行元素取出的公共接口。????
 
 
e.
????List集合?
????????概述
????????????*??List是一個(gè)接口,在util包下,使用的話,只能父類引用指向子類對(duì)象,如下:
????????????????????* List i = new ArrayList(); 但這樣做存在弊端,不能使用子類特有的屬性和方法。
????????????????????* 建議:ArrayList al = new ArrayList();????// 這樣寫。直接new對(duì)象即可直接使用子類屬性和方法。
????????????????????* 因?yàn)槎鄳B(tài)當(dāng) [參數(shù)] 用是比較合適。因?yàn)榭梢愿玫臄U(kuò)展代碼功能。
????????????* 有序集合,有索引,可存儲(chǔ)重復(fù)元素。
????????????* ArrayList底層 數(shù)組實(shí)現(xiàn)。
????????????
????????方法
????????????* void add(int index, E element); 在集合的指定索引位置上添加E對(duì)象。E表示泛型表示任意對(duì)象。
????????????????* 注意:
????????????????????* 當(dāng)添加時(shí)使用不存在的索引,就會(huì)出現(xiàn):IndexOutOfBoundsException 角標(biāo)越界異常。
????????????????????* 添加的索引是: index<=size 并且index>=0 在這個(gè)范圍內(nèi) 就都不會(huì)出錯(cuò)報(bào)異常。
????????????* E remove(int index); 通過集合的索引刪除元素,將被刪除的元素返回。
????????????*?????*??remove的過程不會(huì)將索引自動(dòng)裝箱成對(duì)象。
????????????* E get(int index);??獲取集合指定索引上的元素對(duì)象。
????????????????* get(int index)方法可作為for循環(huán)變量集合的其中一個(gè)條件,配合size()方法便可遍歷出具體集合元素對(duì)象。?????????
????????????* E set(int index, E element); 設(shè)置集合索引上的元素。
????????????* int indexOf(Object o); 返回此列表中第一次出現(xiàn)指定元素的索引位置,如果沒有就返回-1
????????????* List subList(int fromIndex. int toIndex);????返回列表中從指定位置開始到指定位置結(jié)束之間的部分視圖。含頭不含尾的。
????????????
 
????List集合的遍歷
????????概述
????????????* 通過get() 和 size()方法結(jié)合使用遍歷。
????????????* 代碼
????????????????List list = new ArrayList(); //創(chuàng)建集合對(duì)象。
????????????????list.add(new Student("aa",33)); //添加Student元素對(duì)象,等于 Ojbect o = new??Student("aa",33)
????????????????list.add(new Student("bb",23));
????????????????list.add(new Student("cc",13));
????????????????//遍歷集合,使用size()和get()方法去遍歷。
????????????????for(int i=0;i<list.size();i++){
????????????????????Object obj = list.get(i); //獲取每個(gè)集合元素對(duì)象。
????????????????????sop(obj);
????????????????????//如果想獲取具體Student對(duì)象的name和age屬性,就要向下強(qiáng)轉(zhuǎn)對(duì)象,再獲取。因?yàn)楦割惒荒苁褂米宇愄赜械膶傩院托袨椤?/span>
????????????????????Student st = (Student)obj; //向下強(qiáng)轉(zhuǎn)對(duì)象。
????????????????????sop(st.getName()+"..."+st.getAge());
????????????????}
 
 
 
????List集合 --并發(fā)修改異常產(chǎn)生的原因及解決方案
????????* 需求
????????????* 我有一個(gè)集合,請(qǐng)問,我想判斷里面有沒有"world"這個(gè)元素,如果有,我就添加一個(gè)"javaee"元素,請(qǐng)寫代碼實(shí)現(xiàn)。
????????
????????* 問題出現(xiàn)
????????????* 如果使用Iterator普通迭代器 來遍歷集合且同時(shí)添加元素對(duì)象時(shí),就會(huì)出現(xiàn) 并發(fā)修改異常,即ConCurrentModificationException。
????????????* 當(dāng)使用Iterator普通迭代器 來作為遍歷的方式時(shí),一邊遍歷元素對(duì)象并且一邊添加元素對(duì)象,就會(huì)出現(xiàn)這樣的異常。
????????
????????* 解決方案
????????????* 使用List集合特有的一種迭代方式:ListIterator。
????????????* ListIterator迭代器可以 一邊遍歷集合,一邊使用ListIterator迭代器可以特有的add方法添加元素(不是ArrayList的add方法),這樣才不會(huì)有 并發(fā)修改異常 的出現(xiàn)。
????
????????
?????List集合中特有的迭代器 ListIterator 的了解:
????????* boolean hasNext(); 正向順序判斷是否還有下一個(gè)元素。
????????* boolean hasPrevious(); 逆向順序判斷是否還有前一個(gè)元素。
????????* Object next(); 正向順序返回下一個(gè)元素。
????????????* next()獲取元素并將指針向后移動(dòng)一次。?????
????????* Object previous(); 逆向順序返回上一個(gè)元素。????????????
????????????* previous()獲取元素并將指針向前移動(dòng)一次?????
????注意:必須先有正向遍歷,才可以逆向遍歷。????
????
 
 
 
????Vector(1.0)
????????概述
????????????* 有序集合,在util包下,是一個(gè)類。
????????????* 在jdk1.2出現(xiàn)后的集合體系將Vector并入里面,且用 ArrayList代替這個(gè)集合了。
????????????* 底層 數(shù)組實(shí)現(xiàn)。
????????????* 同樣具有 Iterator 迭代器,但該迭代器不是自己的,而是從父類接口List繼承下來的。
????????????* 他有自己遍歷集合的方式:Enumeration
????????
?????特有功能
????????????* void addElement(E obj); 在沒有并入集合系統(tǒng)時(shí),使用的是這個(gè)方法添加元素,當(dāng)并入以后就是用 add() 去添加元素。
????????????* E elementAt(int index); 在沒有并入集合系統(tǒng)時(shí),使用的是這個(gè)方法添加元素,當(dāng)并入以后就是用 nextElement() 去添加元素。
????????????* Enumeration elements(); 獲取枚舉 等同于 Iterator迭代器。
????????????
 
 
 
 
【遍歷集合的幾種方式】
list
????* 使用 toArray() 集合轉(zhuǎn)數(shù)組的方式 + 普通for循環(huán)。
????* 使用 List中的 size() 和 get(int index) 的方式for循環(huán)獲取集合元素。
????* 使用 Iterator迭代器, 直接遍歷集合獲取元素,如果普通迭代器 一邊遍歷集合元素,一邊添加元素,這樣會(huì)一定出現(xiàn):并發(fā)修改異常:ConcurrentModificationException。
????* 使用 List集合中特有的:ListIterator迭代器,一邊遍歷集合元素,一邊使用ListIterato特有的add()方法添加(修改)元素的方式,這樣就不會(huì)出現(xiàn) 并發(fā)修改異常。
 
vector
????* Iterator迭代器
????* Vector vec = new Vector(); Enumeration ele = vec.elements(); 獲取枚舉的方式。
 
 
 
 
f.
????數(shù)組結(jié)構(gòu)之?dāng)?shù)組和鏈表 2017/10/5 0:24:53?
????????概述
????????????* 底層:數(shù)組 --ArrayList,Vector
????????????????* 查詢快,修改快,但增刪慢。(這些都是相對(duì)而言的)
????????????????
????????????* 底層:鏈表 --LinkedList
????????????????* 查詢慢,修改慢,但增刪快。
解析:
????--集合中的 底層:數(shù)組結(jié)構(gòu) 是怎樣的一個(gè)流程??
????????????* 因?yàn)椴糠旨系讓咏Y(jié)構(gòu)是由 數(shù)組 來實(shí)現(xiàn)的,所以會(huì)在底層創(chuàng)建一個(gè)數(shù)組為10的初始長(zhǎng)度,如果要存儲(chǔ)的數(shù)據(jù)超過了這個(gè)數(shù)組初始長(zhǎng)度時(shí)即11個(gè)時(shí),會(huì)再創(chuàng)建一個(gè)比原來大50%的數(shù)組長(zhǎng)度,將原數(shù)組中的數(shù)據(jù)copy到這個(gè)新數(shù)組當(dāng)中,將原數(shù)組扔掉...以此類推。 因?yàn)閿?shù)組一旦創(chuàng)建,長(zhǎng)度就不能被改變,所以隨著存儲(chǔ)數(shù)據(jù)的個(gè)數(shù)越多,數(shù)組的長(zhǎng)度不夠用,就要?jiǎng)?chuàng)建更多的新數(shù)組,這樣會(huì)導(dǎo)致廢棄的舊數(shù)組越來越多成為垃圾,而占用內(nèi)存空間。
????????????????* 底層結(jié)構(gòu):數(shù)組
????????????????????* 什么是數(shù)組?就是一個(gè)容器,里面規(guī)定了初始容量是多少的一個(gè)器皿。比如初始容量就是一個(gè)可以存儲(chǔ)10個(gè)元素的容器,這就是數(shù)組,數(shù)組一旦創(chuàng)建就不可被修改。
????????????????????
????????????????????????* 查詢快,修改快。是因?yàn)閿?shù)組有索引,根據(jù)索引可以方便的 查找 和 修改 對(duì)應(yīng)的數(shù)據(jù)。
????????????????????????
????????????????????????* 增刪慢。因?yàn)槎家獙?duì)索引對(duì)應(yīng)的數(shù)據(jù)進(jìn)行操作,所以慢,如下:。
????????????????????????????* 增加慢,如:在索引2的位置上添加一個(gè)元素E,就要將索引2包含2的元素整體往后移動(dòng)一位。將索引2的元素置出,并放入新添加的E元素。
????????????????????????????* 刪除慢,如:將索引3的元素刪除,就是將3+1的索引位置開始往后的元素往前移動(dòng)一位,移動(dòng)的最末尾的那個(gè)空出來的索引上的元素置為null即可。
????????????????????????????
????--集合中的 底層:鏈表結(jié)構(gòu) 是怎樣的一個(gè)流程??????????????????????????
????????????????????* 底層結(jié)構(gòu):鏈表
????????????????????????* 什么是鏈表? 比如就是一段段自行車的小鏈條。 他們的鏈接就是通過 中間鏈條記錄住前面鏈條的地址值,和再記錄住后面鏈條的地址值,通過這樣的形式將鏈串聯(lián)起來,就是鏈表。
????????????????????????* 前提?鏈表不像數(shù)組是一個(gè)容器有規(guī)矩的索引編號(hào),增和刪 索引都要變化。而鏈表只是通過記錄前后地址值來排列索引而記錄數(shù)據(jù)。
????????????????????????????* 增加快。所以如果想添加一個(gè)元素,可在任意的鏈條中間添加即可,但增加的同樣要記錄住它前后的元素的地址值,從而形成一個(gè)新的鏈表。
????????????????????????????* 刪除快。如果想刪除一個(gè)元素,直接刪除,刪除后的其他兩個(gè)的前后重新拼接一個(gè)新的中間鏈條即可。
????????????
????????????????????????????* 查詢慢:因?yàn)橐扰袛嘁檎业脑鼐嚯x開頭近還是末尾近,確定后。再通過Next(下一個(gè))還是previous(前一個(gè))的方式查詢,這樣對(duì)比數(shù)組直接通過拿索引找元素肯定會(huì)慢些。
????????????????????????????* 修改慢:因?yàn)橐扰袛嘁檎业脑鼐嚯x開頭近還是末尾近,確定后。再通過Next(下一個(gè))還是previous(前一個(gè))的方式查詢,查到后再修改。這樣對(duì)比數(shù)組直接通過拿索引找到元素并修改它肯定會(huì)慢些。
????????????????????????????
????????????????????????????
 
 
 
List集合的三個(gè)子類的特點(diǎn)
????????概述????????
????????????* ArrayList
????????????????* 底層數(shù)據(jù)結(jié)構(gòu):數(shù)組。因?yàn)槭菙?shù)組,所以:查詢快,修改快。但增刪慢。
????????????????* 它是 線程不安全 的,不同步。所以操作速度快,效率高。(最后通過StringBuilder來記錄元素)
????????????* Vector
????????????????* 底層數(shù)據(jù)結(jié)構(gòu):數(shù)組。因?yàn)槭菙?shù)組,所以:CURD都慢。
????????????????* 它是 線程安全 的,同步。所以操作速度慢,效率低。
????????????* LinkedList
????????????????* 底層數(shù)據(jù)結(jié)構(gòu):鏈表,因?yàn)槭擎湵?#xff0c;所以:查詢慢,修改慢,但增刪快。
????????????????* 它是 線程不安全,不同步,所以執(zhí)行效率高。
 
????????????Vector要比ArrayList查詢慢,因?yàn)閂ector是線程安全的。
????????????Vector要比LinkedList增刪慢,因?yàn)閂ectory是數(shù)組結(jié)構(gòu)的,LinkedList是鏈表結(jié)構(gòu)的,鏈表結(jié)構(gòu)增刪快,數(shù)組增刪慢。
 
Vector和ArrayList的區(qū)別
????????????* Vector是 線程安全,所以執(zhí)行效率低。
????????????* ArrayList是 線程不安全的,所以執(zhí)行效率高。
????????????* 共同點(diǎn):底層都是 數(shù)組 實(shí)現(xiàn)的。????
????
ArrayList和LinkedList的區(qū)別?
????????????* ArrayList底層是 數(shù)組結(jié)構(gòu),所以查詢快,修改快,增刪慢。
????????????* LinkedList底層是 鏈表結(jié)構(gòu),所以查詢慢,修改慢,增刪快。
 
????????單列集合Collection下的List有三個(gè)子類,我們到底使用誰?
????????????* 查改多,用ArrayList
????????????* 增刪多,用LinkedList
????????????* 如果都多,就用ArrayList。
 
????
 
【線程安全,意味著有 鎖。】
 
 
 
 
 
 
【面試題】????
 
?????1、集合的繼承體系結(jié)構(gòu)?
????總:
????????集合體系有兩大部分: 單列集合Collection??雙列集合Map
????分:
????????單列結(jié)構(gòu)Collection 下有 List 和 Set
????????????List 有序 有索引,可存儲(chǔ)重復(fù)元素。
????????????????* List下有三個(gè)子類
????????????????????* ArrayList
????????????????????????* 底層結(jié)構(gòu):數(shù)組。查詢快,修改快,增刪慢。
????????????????????????* 線程不安全的,執(zhí)行效率高。
????????????????????* LinkedList
????????????????????????* 底層結(jié)構(gòu):鏈表。查詢慢,修改慢,增刪快。
????????????????????????* 線程不安全的,執(zhí)行效率高。
????????????????????* Vector
????????????????????????* 底層結(jié)構(gòu):數(shù)組,查詢快,修改快,增刪慢。
????????????????????????* 線程安全的,執(zhí)行效率低。
????????????Set??無序,無索引,不可存儲(chǔ)重復(fù)元素。
 
 
????總:
 
 
?????2、數(shù)組和集合區(qū)別?
????????數(shù)組,既可以存儲(chǔ)基本數(shù)據(jù)類型,也可存儲(chǔ)引用數(shù)據(jù)類型,當(dāng)存儲(chǔ)基本數(shù)據(jù)類型存儲(chǔ)的是值,存儲(chǔ)引用數(shù)據(jù)類型時(shí)存儲(chǔ)的是地址值。
????????而集合,只能存儲(chǔ)引用數(shù)據(jù)類型(對(duì)象),當(dāng)集合存儲(chǔ)基本數(shù)據(jù)類型時(shí),會(huì)自動(dòng)裝箱封裝為對(duì)象。(如:int變成Integer對(duì)象, char變成Character對(duì)象,boolean變Boolean對(duì)象)
????????
????????數(shù)組的長(zhǎng)度是固定的,一旦初始化不可更改,不可增長(zhǎng)。
????????集合的長(zhǎng)度是可變的,可以根據(jù)元素的增長(zhǎng)而增長(zhǎng),隨著元素的減少而減少 --(由元素個(gè)數(shù)決定)。
 
?????3、如何獲取字符串、數(shù)組、集合的長(zhǎng)度?
????????????* 字符串: "".length();
????????????* 數(shù)??組: Length屬性;
????????????* 集??合: size()方法;
 
 
 
???4、遍歷集合有哪幾種方式?
????????List
????????????1) 使用 toArray() 將集合轉(zhuǎn)數(shù)組的方式 + 普通for循環(huán)。
????????????2) 使用 List中size()和get(int index)的方法for循環(huán)獲取集合元素。
????????????3) 使用 Iterator迭代器,直接遍歷集合獲取元素。如果使用普通迭代器Iterator 來一邊遍歷集合元素,一邊添加集合元素。一定會(huì)出現(xiàn):并發(fā)修改異常。即:ConcurrentModificationException
????????????4) 使用 List中特有的ListIterator 迭代器,就可以一邊遍歷集合元素,一邊使用ListIterator中特有的add方法添加元素,這樣就不會(huì)有 并發(fā)修改異常 的出現(xiàn)。?
??????????
????????Vector
????????????1) 使用 Iterator迭代器、
????????????2) Vector vec = new Vector(); Enumeration e = evc.elements(); 獲取枚舉的方式。
 
???5、什么時(shí)候用數(shù)組?什么時(shí)候用集合?
????????查改多,用ArrayList
????????增刪多,用LinkedList
????????如果都多,用ArrayList
 
 
???6、來說說你對(duì) ArrayList、LinkedList、Vector的理解?
                            
                        
                        
                        ????對(duì)象數(shù)組 --自定義對(duì)象類
????????概述
????????????* 創(chuàng)建一個(gè)自定義類用于存儲(chǔ)學(xué)生信息,并且獲取到每個(gè)學(xué)生信息 。
????????使用
????????????Student[] s = new Student[5];????//創(chuàng)建student類,用于存儲(chǔ)數(shù)組對(duì)象。
????????????s[0] = new Student("hah", 2);????//第一個(gè)Student數(shù)組的元素,且每個(gè)地址值有所不同
????????????s[1] = new Student("fas", 4);????// 數(shù)組中存儲(chǔ)的元素記錄的都是地址值,通過每個(gè)地址值找到一個(gè)個(gè)的new的元素對(duì)象。
????????????s[2] = new Student("fasd",34);
????????????s[3] = new Student("we", 43);
????????????s[4] = new Student("ad", 23);
????????????for (int i = 0; i < s.length; i++) {
????????????????System.out.println(s[i]);
????????????}?
?????????????????????
????????注意
????????????* 數(shù)組和集合存儲(chǔ) 引用數(shù)據(jù)類型 的時(shí)候,存儲(chǔ)都是地址值,且每個(gè)地址值都有所不同,通過地址值來查找每個(gè)元素對(duì)象。
????????????* 自定義對(duì)象數(shù)組中 存儲(chǔ)的元素記錄的其實(shí)都是地址值,即每個(gè)元素對(duì)象的地址值。 通過每個(gè)索引地址值找到每個(gè) new的元素對(duì)象。
b.
????集合
????????--由來
????????????* 前提:數(shù)組和集合都是容器。
????????????* 因?yàn)閿?shù)組的長(zhǎng)度是固定的,當(dāng)添加的元素超過數(shù)組的長(zhǎng)度需要對(duì)數(shù)組進(jìn)行重新定義,這樣太麻煩。 所以Java在jdk1.2的時(shí)候?yàn)槲覀兲峁┝思项悺<?#xff1a;用于存儲(chǔ)任意對(duì)象,而且長(zhǎng)度可以改變,是隨著元素的增加而增加,隨著元素的減少而減少的,即隨著元素個(gè)數(shù)的變化而變化。
????????????
????????--概述
????????????* 數(shù)組和集合都是容器。
????????????* 集合于jdk1.2時(shí)被提出,長(zhǎng)度可改變,是隨著元素個(gè)數(shù)的變化而變化。
????????數(shù)組和集合區(qū)別
????????????* 可以從兩方面來說:A存儲(chǔ)的類型 和 B存儲(chǔ)的長(zhǎng)度:
????????????* 區(qū)別:
????????????????區(qū)別1:
???????????????????* 數(shù)組既可以存儲(chǔ)基本數(shù)據(jù)類型,也可存儲(chǔ)引用數(shù)據(jù)類型。基本數(shù)據(jù)類型存儲(chǔ)的是值,而引用數(shù)據(jù)類型存儲(chǔ)的是地址值。
???????????????????* 集合只能存儲(chǔ)引用數(shù)據(jù)類型(對(duì)象)集合也可以存儲(chǔ)基本數(shù)據(jù)類型,但存儲(chǔ)的時(shí)候會(huì)自動(dòng)裝箱變成對(duì)象,即int類型的100,存儲(chǔ)到集合中就變成了new Integer(100)。
????????????????區(qū)別2:
????????????????????* 數(shù)組的長(zhǎng)度是固定的,不可自動(dòng)增加。
????????????????????* 集合的長(zhǎng)度是可變的,是根據(jù)元素個(gè)數(shù)的變化而變化。
????????????????????
????????--數(shù)組和集合什么時(shí)候使用
????????????* 如果元素個(gè)數(shù)固定,就用數(shù)組。
????????????* 如果元素個(gè)數(shù)未知,不是固定,就用集合。????--部分集合底層代碼還是用數(shù)組來實(shí)現(xiàn)的,如果超出了數(shù)組的范圍,就創(chuàng)建一個(gè) 大于前者的1.5倍長(zhǎng)度的數(shù)組。增長(zhǎng)后,將原數(shù)組變成垃圾,以此類推。
????
????
????--集合繼承體系關(guān)系圖????????
??????????????-Collection --單列集合根接口
??????????????????* List -存取有序,和數(shù)組相同。有索引,可存儲(chǔ)重復(fù)元素。
??????????????????????* ArrayList???底層 數(shù)組實(shí)現(xiàn)。?
??????????????????????* LinkedList??底層 鏈表實(shí)現(xiàn)。?
??????????????????????* Vector(jdk1.0) 底層 數(shù)組實(shí)現(xiàn)。 --已被ArrayList替代。 之所以和集合命名規(guī)則不同,是集合體系是jdk1.2時(shí)候被提出,而jdk1.0的時(shí)候已經(jīng)有了Vector,因?yàn)閂ector中的功能和集合一樣,所以讓Vector也實(shí)現(xiàn)了List接口并且并入到了集合體系中。
??????????????????* Set -存取無序,無索引,不可存儲(chǔ)重復(fù)元素。
??????????????????????* HashSet????????底層 Hash算法。????元素?zé)o序。
??????????????????????* LinkedHashSet 底層 鏈表結(jié)構(gòu),是set集合中唯一一個(gè)怎么存怎么取的集合,又因?yàn)槭荋ashSet的子類,所以同樣保證了元素的唯一性。
??????????????????????* TreeSet????????底層 二叉樹算法。 元素可以進(jìn)行排序。
??????????????????????
??????????????-Map????--雙列集合根接口
???????????????????* HashMap 底層 哈希算法。 保證鍵的唯一性。
???????????????????* TreeMap 底層 二叉樹。 鍵可以排序。
??????????????????????
c.
????Collection
????????--概述
????????????* Collection是所有 單列集合 的根類接口。
????????????* Map是所有 雙列集合 的根接口。
????????????* 集合是jdk1.2的時(shí)候提出。
????????????* 集合的命名都有一定的規(guī)范:底層是怎么實(shí)現(xiàn)的,前者單詞就是什么,后者是哪個(gè)繼承體系下的。后者單詞就是什么。
????????????如:
????????????????ArrayList 底層數(shù)組實(shí)現(xiàn),屬于List集合下。
????????????????LinkedList 底層鏈表實(shí)現(xiàn),所以List集合下。
????--體系結(jié)構(gòu)圖:????????
????????Collection(單列集合根接口)
????????????* List(有序,有索引,可重復(fù)元素)
????????????????* ArrayList??數(shù)組實(shí)現(xiàn)。存取有序,和數(shù)組一樣。有索引,可存儲(chǔ)重復(fù)元素。
????????????????* LinkedList 鏈表實(shí)現(xiàn)。
????????????????* Vector(jdk1.0) 數(shù)組實(shí)現(xiàn)。之所以和集合命名規(guī)則不同,是因?yàn)樵趈dk1.0時(shí)候出現(xiàn),而集合體系是jdk1.2時(shí)候出現(xiàn),已被ArrayList替代。
????????????* Set (無序,無索引,不可重復(fù)元素)
????????????????* HastSet 哈希算法。
????????????????* TreeSet 二叉樹算法。
????????????????
????????注意:List是一個(gè)不可插隊(duì)的插入對(duì)象。
????????
d.
????Collection集合的基本功能
????????概述
??????????* util包下,用時(shí)需導(dǎo)包。
??????????* Collection 是接口,用時(shí)只能:父類引用指向子類對(duì)象,即:????Collection c = new ArrayList();
??????????* Collection 單列集合 中的根接口。
??????????* Collection 表示一組對(duì)象,這些對(duì)象也稱為 collection 的元素。一些 collection 允許有重復(fù)的元素(list),而另一些則不允許(set)。一些collection 是有序的(list),而另一些則是無序的(set)。
??????????* JDK不提供此接口的任何直接 實(shí)現(xiàn):它提供更具體的子接口(如 Set 和 List)實(shí)現(xiàn)。
????????常用方法
?????????* boolean add(Object obj);?????????添加對(duì)象 可添加任意對(duì)象。?????
?????????*?????????????????????????????????????????????結(jié)果Boolean永遠(yuǎn)都是true。那什么時(shí)候是false? 只有當(dāng)set集合存儲(chǔ)重復(fù)元素的時(shí)候,返回false。
?????????*?????????????????????????????????????????????所以一般我們不用返回值類型,自己將對(duì)象添加到集合中即可。即:c.add("sfa");
?????????*?
?????????* boolean remove(Object obj);?????刪除對(duì)象 可刪除任意對(duì)象。可以是基本數(shù)據(jù)類型,到時(shí)候會(huì)自動(dòng)裝箱成對(duì)象。
?????????* void clear();?????????????????????清空集合元素
?????????* boolean contains(Object o);????????判斷是否包含指定元素
?????????* boolean isEmpty();????????????????判斷集合是否為空,為空就返回true,否則為false。
?????????* int size();????????????????????????獲取集合中的元素個(gè)數(shù)
?????????
????注意:1)add如果是List集合,就一直返回true,因?yàn)閘ist集合中是可以存儲(chǔ)重復(fù)元素的。
?????????????如果是set集合用add存儲(chǔ)重復(fù)元素,就會(huì)返回false。
?????????2)ArrayList的父類的父類重寫了toString方法,所以在打印對(duì)象的引用時(shí)輸出的結(jié)果不是Object的??toString 的結(jié)果,而是集合特有的:[元素]的形式。
?????????collectionXxx.java使用了未經(jīng)檢查或不安全的操作.
?????????注意:要了解詳細(xì)信息,請(qǐng)使用 -Xlint:unchecked重新編譯.
????????????java編譯器認(rèn)為該程序存在安全隱患
????????????溫馨提示:這不是編譯失敗,所以先不用理會(huì),等 學(xué)了泛型你就知道了
????toArray() 集合的遍歷之集合轉(zhuǎn)數(shù)組遍歷的功能
????????集合遍歷
????????????* 就是依次獲取集合中的每個(gè)元素。
????????????* 集合轉(zhuǎn)數(shù)組,就可以實(shí)現(xiàn)對(duì)集合的遍歷。
????????????* Object[] toArray(); 集合轉(zhuǎn)數(shù)組的方式就可以遍歷集合中的每個(gè)元素。
????????代碼
????????????//自定義 Bean對(duì)象 的遍歷方式。
????????????????????Collection c2 = new ArrayList(); //創(chuàng)建單列集合對(duì)象。
????????????????????c2.add(new Student("哈哈",23));??//等同于 Object o = new Student("哈哈",23);
????????????????????c2.add(new Student("嘻嘻",25));
????????????????????c2.add(new Student("么么",332));
????????????????????c2.add(new Student("啦啦",645));
????????????????????
????????????????????Object[] array2 = c2.toArray();
????????????????????for (int i = 0; i < array2.length; i++) {
?????????????????????????System.out.println(array2[i]); //獲取集合中所有的元素對(duì)象。
?????????????????????????
????????????//?????????????如果想獲取每個(gè)元素對(duì)象中的Name 或 age,就要向下轉(zhuǎn)型,即Object轉(zhuǎn)成Student對(duì)象。現(xiàn)在的array2[i] 就是Ojbect對(duì)象。
????????????//????????????(看左邊的類型,如果左邊是Object對(duì)象 就是向上轉(zhuǎn)型,如果左邊是Student對(duì)象,就是向下轉(zhuǎn)型)
?????????????????????????Student st =(Student)array2[i];????//向下轉(zhuǎn)型。將Object的array2轉(zhuǎn)成Student。
?????????????????????????System.out.println("姓名:"+st.getName()+"??年齡:"+st.getAge());
????????????????????}
????Collection集合中方法帶有All后綴的功能
????????????* boolean addAll(Collection c);????添加集合。
????????????????* 如:
????????????????????* c1集合有對(duì)象:abcd??c2集合有對(duì)象:ef
????????????????????* c1.addAll(c2); 將c2集合中的每個(gè)對(duì)象添加c1中,結(jié)果為:[a,b,c,d,e,f]
????????????????????* c1.add(c2); 將c2看做是一個(gè)整個(gè)對(duì)象添加到c1中,結(jié)果為:[a,b,c,d,[e,f]]
????????????????
????????????* boolean removeAll(Collection c);??刪除集合或刪除集合的元素,刪除的是兩個(gè)集合的交集為true,如果刪除的是兩個(gè)集合沒有的交集,就是false。
????????????* boolean containsAll(Collection c); 是否一個(gè)集合包含另一個(gè)集合的所有元素。如果全包含就為true,否之為false。
????????????* boolean retainAll(Collection c);??取出兩個(gè)集合之間的交集。
????????????????* 注意:如果調(diào)用的集合改變就返回true, 如果調(diào)用的集合沒有改變就返回false。
?????????????????????如:
?????????????????????????1) c1集合有:abcd?????c2集合有 ab????c1.retainAll(c2);??取交集c1結(jié)果為:ab,c1改變了,所以返回true。?????
?????????????????????????2) c1集合有:abcd?????c2集合有 z?????c1.retainAll(c2);??取交集c1結(jié)果為:[], 但c1還是改變,所以也返回true。
?????????????????????????3) c1集合有:abcd?????c2集合有 abcdefg?????c1.retainAll(c2);???取交集c1結(jié)果為:abcd,c1沒有改變,所以為false。
?????????????????????這就是retainAll的特殊之處,主要是 前者跟后者比較,前者的結(jié)果是否改變,如果改變就是true,如果沒變就是false。?????
????
????Collection集合的Iterator迭代器的遍歷方式
????????????概述
????????????????* 集合用于存儲(chǔ)元素,存儲(chǔ)的元素如果需要查看,就要使用迭代器的方式。
????????????使用
????????????????* 使用 Iterator 的方式來迭代。
????????????????* 關(guān)鍵方法:
????????????????????* hasNext(); 判斷是否還有下一個(gè)元素,如果有就返回true。
????????????????????* next(); 返回迭代的下一個(gè)元素,即將集合中的元素取出。
????????????????????????* next具有將指針向下移一位的功能。
????Collection存儲(chǔ)自定義對(duì)象并遍歷
????????????Collection c = new ArrayList(); // 創(chuàng)建集合對(duì)象。父類引用指向子類對(duì)象
????????????c.add(new Student("趙白石",43));??//等等于: Object??obj = new Student("趙白石",43); 即父類引用指向子類對(duì)象,obj不能使用子類特有的屬性和行為,即使用只能靠向下轉(zhuǎn)型的方式才能夠子類特有的屬性和行為。
????????????c.add(new Student("沈星移",33));
????????????c.add(new Student("周瑩",40));
????????????c.add(new Student("吳聘",42));
????????????
//????????方式一:while來做
????????/*????Iterator it = c.iterator();
????????????while(it.hasNext()){
????????????????Student st = (Student)it.next(); //向下強(qiáng)轉(zhuǎn)。 將it.next的Iterator的對(duì)象向下強(qiáng)轉(zhuǎn)成Student對(duì)象。只有向下轉(zhuǎn)型,才能使用子類特有的屬性和行為。
????????????????String name = st.getName();?
????????????????int age = st.getAge();
????????????????System.out.println("姓名:"+name+".....年齡:"+age);
????????????}*/
//【注意:向下轉(zhuǎn)型,才能使用子類特有的屬性和行為】
????????????
//????????方式二:for循環(huán)來做
????????for (Iterator it = c.iterator(); it.hasNext();) {
????????????????Student s = (Student)it.next();??//向下強(qiáng)轉(zhuǎn)。將it.next的Iterator的對(duì)象向下強(qiáng)轉(zhuǎn)成Student對(duì)象。這樣就能獲取子類特有的屬性和行為。
????????????????System.out.println(s.getName()+"..."+s.getAge());
????????}
????}
????--迭代器的原理及源碼解析
?????????原理????
?????????????迭代器是對(duì)集合進(jìn)行遍歷的,而每個(gè)集合內(nèi)部的存儲(chǔ)結(jié)構(gòu)都是不同,所以每個(gè)集合的存和取的方式也都不同的。那么就需要在每一個(gè)類中都去定義hasNext()方法 和 next()方法,這樣做可以方便的判斷是否有下一個(gè)元素和返回集合中的當(dāng)前元素。但是這樣整個(gè)集合體系看起來就會(huì)過于臃腫。所以就將迭代器向上抽取出一個(gè)接口,然后在每個(gè)類的內(nèi)部去定義自己的迭代方式。 這樣做的好處有二:
?????????????第一:規(guī)定了整個(gè)集合體系的遍歷方式通過通過hasNext()和next()方法來實(shí)現(xiàn)的。第二:代碼由底層內(nèi)部實(shí)現(xiàn),使用者無需關(guān)心怎么實(shí)現(xiàn)的,會(huì)用即可。
????????迭代器的原理:
????????迭代器是用來遍歷集合。因?yàn)榧系牡讓訑?shù)據(jù)結(jié)構(gòu)不同,就導(dǎo)致集合存取元素的方式不同,如果每個(gè)集合類都定義自己的存取方式,這樣做是可以的,但是會(huì)讓整個(gè)繼承體系很冗余,臃腫。所以我們經(jīng)過不斷的向上抽取,最終定義成了接口。
????????這樣做的好處有兩個(gè):
????????????A:更規(guī)范。
????????????B:我們不用管底層是怎么實(shí)現(xiàn),只要會(huì)用就可以了。
????????
????????
????????迭代器源碼解析
??????????????* 1,在eclipse中ctrl + shift + t找到ArrayList類
??????????????* 2,ctrl+o查找iterator()方法
??????????????* 3,查看返回值類型是new Itr(),說明Itr這個(gè)類實(shí)現(xiàn)Iterator接口
??????????????* 4,查找Itr這個(gè)內(nèi)部類,發(fā)現(xiàn)重寫了Iterator中的所有抽象方法?
????????????
????????Iterator iterator(); 該對(duì)象必須依賴具體的集合容器,因?yàn)槊總€(gè)集合容器的內(nèi)部數(shù)據(jù)結(jié)構(gòu)不同,所以該迭代器對(duì)象是在集合容器中進(jìn)行內(nèi)部實(shí)現(xiàn)的,也就是說iterator()方法在每個(gè)集合容器中的實(shí)現(xiàn)方式時(shí)不同的。
????????對(duì)于調(diào)用者來說,具體的實(shí)現(xiàn)過程無需知道,只要通過該集合容器獲取到該實(shí)現(xiàn)的迭代器對(duì)象即可,也就是iterator方法。
????????Iterator接口就是對(duì)所有單列集合根接口Collection容器進(jìn)行元素取出的公共接口。????
e.
????List集合?
????????概述
????????????*??List是一個(gè)接口,在util包下,使用的話,只能父類引用指向子類對(duì)象,如下:
????????????????????* List i = new ArrayList(); 但這樣做存在弊端,不能使用子類特有的屬性和方法。
????????????????????* 建議:ArrayList al = new ArrayList();????// 這樣寫。直接new對(duì)象即可直接使用子類屬性和方法。
????????????????????* 因?yàn)槎鄳B(tài)當(dāng) [參數(shù)] 用是比較合適。因?yàn)榭梢愿玫臄U(kuò)展代碼功能。
????????????* 有序集合,有索引,可存儲(chǔ)重復(fù)元素。
????????????* ArrayList底層 數(shù)組實(shí)現(xiàn)。
????????????
????????方法
????????????* void add(int index, E element); 在集合的指定索引位置上添加E對(duì)象。E表示泛型表示任意對(duì)象。
????????????????* 注意:
????????????????????* 當(dāng)添加時(shí)使用不存在的索引,就會(huì)出現(xiàn):IndexOutOfBoundsException 角標(biāo)越界異常。
????????????????????* 添加的索引是: index<=size 并且index>=0 在這個(gè)范圍內(nèi) 就都不會(huì)出錯(cuò)報(bào)異常。
????????????* E remove(int index); 通過集合的索引刪除元素,將被刪除的元素返回。
????????????*?????*??remove的過程不會(huì)將索引自動(dòng)裝箱成對(duì)象。
????????????* E get(int index);??獲取集合指定索引上的元素對(duì)象。
????????????????* get(int index)方法可作為for循環(huán)變量集合的其中一個(gè)條件,配合size()方法便可遍歷出具體集合元素對(duì)象。?????????
????????????* E set(int index, E element); 設(shè)置集合索引上的元素。
????????????* int indexOf(Object o); 返回此列表中第一次出現(xiàn)指定元素的索引位置,如果沒有就返回-1
????????????* List subList(int fromIndex. int toIndex);????返回列表中從指定位置開始到指定位置結(jié)束之間的部分視圖。含頭不含尾的。
????????????
????List集合的遍歷
????????概述
????????????* 通過get() 和 size()方法結(jié)合使用遍歷。
????????????* 代碼
????????????????List list = new ArrayList(); //創(chuàng)建集合對(duì)象。
????????????????list.add(new Student("aa",33)); //添加Student元素對(duì)象,等于 Ojbect o = new??Student("aa",33)
????????????????list.add(new Student("bb",23));
????????????????list.add(new Student("cc",13));
????????????????//遍歷集合,使用size()和get()方法去遍歷。
????????????????for(int i=0;i<list.size();i++){
????????????????????Object obj = list.get(i); //獲取每個(gè)集合元素對(duì)象。
????????????????????sop(obj);
????????????????????//如果想獲取具體Student對(duì)象的name和age屬性,就要向下強(qiáng)轉(zhuǎn)對(duì)象,再獲取。因?yàn)楦割惒荒苁褂米宇愄赜械膶傩院托袨椤?/span>
????????????????????Student st = (Student)obj; //向下強(qiáng)轉(zhuǎn)對(duì)象。
????????????????????sop(st.getName()+"..."+st.getAge());
????????????????}
????List集合 --并發(fā)修改異常產(chǎn)生的原因及解決方案
????????* 需求
????????????* 我有一個(gè)集合,請(qǐng)問,我想判斷里面有沒有"world"這個(gè)元素,如果有,我就添加一個(gè)"javaee"元素,請(qǐng)寫代碼實(shí)現(xiàn)。
????????
????????* 問題出現(xiàn)
????????????* 如果使用Iterator普通迭代器 來遍歷集合且同時(shí)添加元素對(duì)象時(shí),就會(huì)出現(xiàn) 并發(fā)修改異常,即ConCurrentModificationException。
????????????* 當(dāng)使用Iterator普通迭代器 來作為遍歷的方式時(shí),一邊遍歷元素對(duì)象并且一邊添加元素對(duì)象,就會(huì)出現(xiàn)這樣的異常。
????????
????????* 解決方案
????????????* 使用List集合特有的一種迭代方式:ListIterator。
????????????* ListIterator迭代器可以 一邊遍歷集合,一邊使用ListIterator迭代器可以特有的add方法添加元素(不是ArrayList的add方法),這樣才不會(huì)有 并發(fā)修改異常 的出現(xiàn)。
????
????????
?????List集合中特有的迭代器 ListIterator 的了解:
????????* boolean hasNext(); 正向順序判斷是否還有下一個(gè)元素。
????????* boolean hasPrevious(); 逆向順序判斷是否還有前一個(gè)元素。
????????* Object next(); 正向順序返回下一個(gè)元素。
????????????* next()獲取元素并將指針向后移動(dòng)一次。?????
????????* Object previous(); 逆向順序返回上一個(gè)元素。????????????
????????????* previous()獲取元素并將指針向前移動(dòng)一次?????
????注意:必須先有正向遍歷,才可以逆向遍歷。????
????
????Vector(1.0)
????????概述
????????????* 有序集合,在util包下,是一個(gè)類。
????????????* 在jdk1.2出現(xiàn)后的集合體系將Vector并入里面,且用 ArrayList代替這個(gè)集合了。
????????????* 底層 數(shù)組實(shí)現(xiàn)。
????????????* 同樣具有 Iterator 迭代器,但該迭代器不是自己的,而是從父類接口List繼承下來的。
????????????* 他有自己遍歷集合的方式:Enumeration
????????
?????特有功能
????????????* void addElement(E obj); 在沒有并入集合系統(tǒng)時(shí),使用的是這個(gè)方法添加元素,當(dāng)并入以后就是用 add() 去添加元素。
????????????* E elementAt(int index); 在沒有并入集合系統(tǒng)時(shí),使用的是這個(gè)方法添加元素,當(dāng)并入以后就是用 nextElement() 去添加元素。
????????????* Enumeration elements(); 獲取枚舉 等同于 Iterator迭代器。
????????????
【遍歷集合的幾種方式】
list
????* 使用 toArray() 集合轉(zhuǎn)數(shù)組的方式 + 普通for循環(huán)。
????* 使用 List中的 size() 和 get(int index) 的方式for循環(huán)獲取集合元素。
????* 使用 Iterator迭代器, 直接遍歷集合獲取元素,如果普通迭代器 一邊遍歷集合元素,一邊添加元素,這樣會(huì)一定出現(xiàn):并發(fā)修改異常:ConcurrentModificationException。
????* 使用 List集合中特有的:ListIterator迭代器,一邊遍歷集合元素,一邊使用ListIterato特有的add()方法添加(修改)元素的方式,這樣就不會(huì)出現(xiàn) 并發(fā)修改異常。
vector
????* Iterator迭代器
????* Vector vec = new Vector(); Enumeration ele = vec.elements(); 獲取枚舉的方式。
f.
????數(shù)組結(jié)構(gòu)之?dāng)?shù)組和鏈表 2017/10/5 0:24:53?
????????概述
????????????* 底層:數(shù)組 --ArrayList,Vector
????????????????* 查詢快,修改快,但增刪慢。(這些都是相對(duì)而言的)
????????????????
????????????* 底層:鏈表 --LinkedList
????????????????* 查詢慢,修改慢,但增刪快。
解析:
????--集合中的 底層:數(shù)組結(jié)構(gòu) 是怎樣的一個(gè)流程??
????????????* 因?yàn)椴糠旨系讓咏Y(jié)構(gòu)是由 數(shù)組 來實(shí)現(xiàn)的,所以會(huì)在底層創(chuàng)建一個(gè)數(shù)組為10的初始長(zhǎng)度,如果要存儲(chǔ)的數(shù)據(jù)超過了這個(gè)數(shù)組初始長(zhǎng)度時(shí)即11個(gè)時(shí),會(huì)再創(chuàng)建一個(gè)比原來大50%的數(shù)組長(zhǎng)度,將原數(shù)組中的數(shù)據(jù)copy到這個(gè)新數(shù)組當(dāng)中,將原數(shù)組扔掉...以此類推。 因?yàn)閿?shù)組一旦創(chuàng)建,長(zhǎng)度就不能被改變,所以隨著存儲(chǔ)數(shù)據(jù)的個(gè)數(shù)越多,數(shù)組的長(zhǎng)度不夠用,就要?jiǎng)?chuàng)建更多的新數(shù)組,這樣會(huì)導(dǎo)致廢棄的舊數(shù)組越來越多成為垃圾,而占用內(nèi)存空間。
????????????????* 底層結(jié)構(gòu):數(shù)組
????????????????????* 什么是數(shù)組?就是一個(gè)容器,里面規(guī)定了初始容量是多少的一個(gè)器皿。比如初始容量就是一個(gè)可以存儲(chǔ)10個(gè)元素的容器,這就是數(shù)組,數(shù)組一旦創(chuàng)建就不可被修改。
????????????????????
????????????????????????* 查詢快,修改快。是因?yàn)閿?shù)組有索引,根據(jù)索引可以方便的 查找 和 修改 對(duì)應(yīng)的數(shù)據(jù)。
????????????????????????
????????????????????????* 增刪慢。因?yàn)槎家獙?duì)索引對(duì)應(yīng)的數(shù)據(jù)進(jìn)行操作,所以慢,如下:。
????????????????????????????* 增加慢,如:在索引2的位置上添加一個(gè)元素E,就要將索引2包含2的元素整體往后移動(dòng)一位。將索引2的元素置出,并放入新添加的E元素。
????????????????????????????* 刪除慢,如:將索引3的元素刪除,就是將3+1的索引位置開始往后的元素往前移動(dòng)一位,移動(dòng)的最末尾的那個(gè)空出來的索引上的元素置為null即可。
????????????????????????????
????--集合中的 底層:鏈表結(jié)構(gòu) 是怎樣的一個(gè)流程??????????????????????????
????????????????????* 底層結(jié)構(gòu):鏈表
????????????????????????* 什么是鏈表? 比如就是一段段自行車的小鏈條。 他們的鏈接就是通過 中間鏈條記錄住前面鏈條的地址值,和再記錄住后面鏈條的地址值,通過這樣的形式將鏈串聯(lián)起來,就是鏈表。
????????????????????????* 前提?鏈表不像數(shù)組是一個(gè)容器有規(guī)矩的索引編號(hào),增和刪 索引都要變化。而鏈表只是通過記錄前后地址值來排列索引而記錄數(shù)據(jù)。
????????????????????????????* 增加快。所以如果想添加一個(gè)元素,可在任意的鏈條中間添加即可,但增加的同樣要記錄住它前后的元素的地址值,從而形成一個(gè)新的鏈表。
????????????????????????????* 刪除快。如果想刪除一個(gè)元素,直接刪除,刪除后的其他兩個(gè)的前后重新拼接一個(gè)新的中間鏈條即可。
????????????
????????????????????????????* 查詢慢:因?yàn)橐扰袛嘁檎业脑鼐嚯x開頭近還是末尾近,確定后。再通過Next(下一個(gè))還是previous(前一個(gè))的方式查詢,這樣對(duì)比數(shù)組直接通過拿索引找元素肯定會(huì)慢些。
????????????????????????????* 修改慢:因?yàn)橐扰袛嘁檎业脑鼐嚯x開頭近還是末尾近,確定后。再通過Next(下一個(gè))還是previous(前一個(gè))的方式查詢,查到后再修改。這樣對(duì)比數(shù)組直接通過拿索引找到元素并修改它肯定會(huì)慢些。
????????????????????????????
????????????????????????????
List集合的三個(gè)子類的特點(diǎn)
????????概述????????
????????????* ArrayList
????????????????* 底層數(shù)據(jù)結(jié)構(gòu):數(shù)組。因?yàn)槭菙?shù)組,所以:查詢快,修改快。但增刪慢。
????????????????* 它是 線程不安全 的,不同步。所以操作速度快,效率高。(最后通過StringBuilder來記錄元素)
????????????* Vector
????????????????* 底層數(shù)據(jù)結(jié)構(gòu):數(shù)組。因?yàn)槭菙?shù)組,所以:CURD都慢。
????????????????* 它是 線程安全 的,同步。所以操作速度慢,效率低。
????????????* LinkedList
????????????????* 底層數(shù)據(jù)結(jié)構(gòu):鏈表,因?yàn)槭擎湵?#xff0c;所以:查詢慢,修改慢,但增刪快。
????????????????* 它是 線程不安全,不同步,所以執(zhí)行效率高。
????????????Vector要比ArrayList查詢慢,因?yàn)閂ector是線程安全的。
????????????Vector要比LinkedList增刪慢,因?yàn)閂ectory是數(shù)組結(jié)構(gòu)的,LinkedList是鏈表結(jié)構(gòu)的,鏈表結(jié)構(gòu)增刪快,數(shù)組增刪慢。
Vector和ArrayList的區(qū)別
????????????* Vector是 線程安全,所以執(zhí)行效率低。
????????????* ArrayList是 線程不安全的,所以執(zhí)行效率高。
????????????* 共同點(diǎn):底層都是 數(shù)組 實(shí)現(xiàn)的。????
????
ArrayList和LinkedList的區(qū)別?
????????????* ArrayList底層是 數(shù)組結(jié)構(gòu),所以查詢快,修改快,增刪慢。
????????????* LinkedList底層是 鏈表結(jié)構(gòu),所以查詢慢,修改慢,增刪快。
????????單列集合Collection下的List有三個(gè)子類,我們到底使用誰?
????????????* 查改多,用ArrayList
????????????* 增刪多,用LinkedList
????????????* 如果都多,就用ArrayList。
????
【線程安全,意味著有 鎖。】
【面試題】????
?????1、集合的繼承體系結(jié)構(gòu)?
????總:
????????集合體系有兩大部分: 單列集合Collection??雙列集合Map
????分:
????????單列結(jié)構(gòu)Collection 下有 List 和 Set
????????????List 有序 有索引,可存儲(chǔ)重復(fù)元素。
????????????????* List下有三個(gè)子類
????????????????????* ArrayList
????????????????????????* 底層結(jié)構(gòu):數(shù)組。查詢快,修改快,增刪慢。
????????????????????????* 線程不安全的,執(zhí)行效率高。
????????????????????* LinkedList
????????????????????????* 底層結(jié)構(gòu):鏈表。查詢慢,修改慢,增刪快。
????????????????????????* 線程不安全的,執(zhí)行效率高。
????????????????????* Vector
????????????????????????* 底層結(jié)構(gòu):數(shù)組,查詢快,修改快,增刪慢。
????????????????????????* 線程安全的,執(zhí)行效率低。
????????????Set??無序,無索引,不可存儲(chǔ)重復(fù)元素。
????總:
?????2、數(shù)組和集合區(qū)別?
????????數(shù)組,既可以存儲(chǔ)基本數(shù)據(jù)類型,也可存儲(chǔ)引用數(shù)據(jù)類型,當(dāng)存儲(chǔ)基本數(shù)據(jù)類型存儲(chǔ)的是值,存儲(chǔ)引用數(shù)據(jù)類型時(shí)存儲(chǔ)的是地址值。
????????而集合,只能存儲(chǔ)引用數(shù)據(jù)類型(對(duì)象),當(dāng)集合存儲(chǔ)基本數(shù)據(jù)類型時(shí),會(huì)自動(dòng)裝箱封裝為對(duì)象。(如:int變成Integer對(duì)象, char變成Character對(duì)象,boolean變Boolean對(duì)象)
????????
????????數(shù)組的長(zhǎng)度是固定的,一旦初始化不可更改,不可增長(zhǎng)。
????????集合的長(zhǎng)度是可變的,可以根據(jù)元素的增長(zhǎng)而增長(zhǎng),隨著元素的減少而減少 --(由元素個(gè)數(shù)決定)。
?????3、如何獲取字符串、數(shù)組、集合的長(zhǎng)度?
????????????* 字符串: "".length();
????????????* 數(shù)??組: Length屬性;
????????????* 集??合: size()方法;
???4、遍歷集合有哪幾種方式?
????????List
????????????1) 使用 toArray() 將集合轉(zhuǎn)數(shù)組的方式 + 普通for循環(huán)。
????????????2) 使用 List中size()和get(int index)的方法for循環(huán)獲取集合元素。
????????????3) 使用 Iterator迭代器,直接遍歷集合獲取元素。如果使用普通迭代器Iterator 來一邊遍歷集合元素,一邊添加集合元素。一定會(huì)出現(xiàn):并發(fā)修改異常。即:ConcurrentModificationException
????????????4) 使用 List中特有的ListIterator 迭代器,就可以一邊遍歷集合元素,一邊使用ListIterator中特有的add方法添加元素,這樣就不會(huì)有 并發(fā)修改異常 的出現(xiàn)。?
??????????
????????Vector
????????????1) 使用 Iterator迭代器、
????????????2) Vector vec = new Vector(); Enumeration e = evc.elements(); 獲取枚舉的方式。
???5、什么時(shí)候用數(shù)組?什么時(shí)候用集合?
????????查改多,用ArrayList
????????增刪多,用LinkedList
????????如果都多,用ArrayList
???6、來說說你對(duì) ArrayList、LinkedList、Vector的理解?
總結(jié)
以上是生活随笔為你收集整理的Day15 --框架集合 Collection集合 和 List 集合的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: SQL创建某一年日历表
 - 下一篇: 基于STM32F103单片机的智能药盒喂