紅知博客

          知其然,亦知其所以然
          posts - 32, comments - 35, trackbacks - 0, articles - 0

          一、數(shù)組與向量(Vector)

          A、vector與數(shù)組類似,但能被擴(kuò)大和縮小。

          向量與數(shù)組的區(qū)別:

              1、Java的數(shù)組可存儲(chǔ)任何類型的數(shù)組元素,包括數(shù)值類型和所有類類型
                            
              2、Java向量只能存儲(chǔ)對(duì)象類的實(shí)例。                  

              向量能重定位和調(diào)整自己的容量。缺省時(shí),向量重定位一次,其容量就擴(kuò)大一倍,呈指數(shù)增長(zhǎng),所以應(yīng)指定容量增量,做為向量構(gòu)造函數(shù)的第二個(gè)參數(shù),來創(chuàng)建向量:

              Vector itemsOrdered = new Vector(3.10);這樣向量每重定位一次,其容量都增加10個(gè)元素。

              v.size()返回向量中的元素個(gè)數(shù),等價(jià)于 arry.length();

              如果向量已達(dá)到其永久大小,則可調(diào)用tirmToSize 方法,將內(nèi)存塊大小調(diào)整到剛好能容納當(dāng)前個(gè)數(shù)的向量元素  

              向量中不能用方便的[]句法,而必須用elementAt 和setSlementAt 方法來訪問或修改元素。

              

               數(shù)組:x = a[i](訪問)         a[i] = x;(修改)

               向量:x = v.elementAt(i)     v.SetElementAt(x.i)

          B、Choice類:類似Combox 選框

              Choice ColorChooser = newChoice();

              ColorChooser.add("Green");

              ColorChooser.add("Red");

              ColorChooser.add("Blue");

              Panel p = new Panel(); p.add(ColorChooser);(在面板上顯示Combox組合選框)













          二、ArrayList的使用方法以及與vector的對(duì)比

          1、什么是ArrayList
               ArrayList就是傳說中的動(dòng)態(tài)數(shù)組,用MSDN中的說法,就是Array的復(fù)雜版本,它提供了如下一些好處:

          • 動(dòng)態(tài)的增加和減少元素
          • 實(shí)現(xiàn)了ICollectionIList接口
          • 靈活的設(shè)置數(shù)組的大小


          2、如何使用ArrayList
              最簡(jiǎn)單的例子:
          ArrayList List = new ArrayList();
          for( int i=0;i<10;i++ ) //
          給數(shù)組增加10個(gè)Int元素
          List.Add(i);
          //..
          程序做一些處理
          List.RemoveAt(5);//
          將第6個(gè)元素移除
          for( int i=0;i<3;i++ ) //
          再增加3個(gè)元素
          List.Add(i+20);
          Int32[] values = (Int32[])List.ToArray(typeof(Int32));//
          返回ArrayList包含的數(shù)組

          這是一個(gè)簡(jiǎn)單的例子,雖然沒有包含ArrayList所有的方法,但是可以反映出ArrayList最常用的用法

          3
          ArrayList重要的方法和屬性
          1)構(gòu)造器
               ArrayList
          提供了三個(gè)構(gòu)造器:
          public ArrayList();
          默認(rèn)的構(gòu)造器,將會(huì)以默認(rèn)(16)的大小來初始化內(nèi)部的數(shù)組
          public ArrayList(ICollection);
          用一個(gè)ICollection對(duì)象來構(gòu)造,并將該集合的元素添加到ArrayList
          public ArrayList(int);
          用指定的大小來初始化內(nèi)部的數(shù)組

          2IsSynchronized屬性和ArrayList.Synchronized方法
               IsSynchronized
          屬性指示當(dāng)前的ArrayList實(shí)例是否支持線程同步,而ArrayList.Synchronized靜態(tài)方法則會(huì)返回一個(gè)ArrayList的線程同步的封裝。
              如果使用非線程同步的實(shí)例,那么在多線程訪問的時(shí)候,需要自己手動(dòng)調(diào)用lock來保持線程同步,例如:
          ArrayList list = new ArrayList();
          //...
          lock( list.SyncRoot ) //
          當(dāng)ArrayList為非線程包裝的時(shí)候,SyncRoot屬性其實(shí)就是它自己,但是為了滿足ICollectionSyncRoot定義,這里還是使用SyncRoot來保持源代碼的規(guī)范性
          {
          list.Add(
          Add a Item );
          }

               
          如果使用ArrayList.Synchronized方法返回的實(shí)例,那么就不用考慮線程同步的問題,這個(gè)實(shí)例本身就是線程安全的,實(shí)際上ArrayList內(nèi)部實(shí)現(xiàn)了一個(gè)保證線程同步的內(nèi)部類,ArrayList.Synchronized返回的就是這個(gè)類的實(shí)例,它里面的每個(gè)屬性都是用了lock關(guān)鍵字來保證線程同步。

          ****

          但是,使用這個(gè)方法(ArrayList.Synchronized)并不能保證枚舉的同步,例如,一個(gè)線程正在刪除或添加集合項(xiàng),而另一個(gè)線程同時(shí)進(jìn)行枚舉,這時(shí)枚舉將會(huì)拋出異常。所以,在枚舉的時(shí)候,你必須明確使用 SyncRoot 鎖定這個(gè)集合。

          HashtableArrayList關(guān)于線程安全性的使用方法類似。

          ****

          3Count屬性和Capacity屬性
               Count
          屬性是目前ArrayList包含的元素的數(shù)量,這個(gè)屬性是只讀的。
          Capacity
          屬性是目前ArrayList能夠包含的最大數(shù)量,可以手動(dòng)的設(shè)置這個(gè)屬性,但是當(dāng)設(shè)置為小于Count值的時(shí)候會(huì)引發(fā)一個(gè)異常。

          4AddAddRangeRemoveRemoveAtRemoveRangeInsertInsertRange
              
          這幾個(gè)方法比較類似
          Add
          方法用于添加一個(gè)元素到當(dāng)前列表的末尾
          AddRange
          方法用于添加一批元素到當(dāng)前列表的末尾
          Remove
          方法用于刪除一個(gè)元素,通過元素本身的引用來刪除
          RemoveAt
          方法用于刪除一個(gè)元素,通過索引值來刪除
          RemoveRange
          用于刪除一批元素,通過指定開始的索引和刪除的數(shù)量來刪除
          Insert
          用于添加一個(gè)元素到指定位置,列表后面的元素依次往后移動(dòng)
          InsertRange
          用于從指定位置開始添加一批元素,列表后面的元素依次往后移動(dòng)

              
          另外,還有幾個(gè)類似的方法:
          Clear
          方法用于清除現(xiàn)有所有的元素
          Contains
          方法用來查找某個(gè)對(duì)象在不在列表之中

              
          其他的我就不一一累贅了,大家可以查看MSDN,上面講的更仔細(xì)
          5TrimSize方法
              
          這個(gè)方法用于將ArrayList固定到實(shí)際元素的大小,當(dāng)動(dòng)態(tài)數(shù)組元素確定不在添加的時(shí)候,可以調(diào)用這個(gè)方法來釋放空余的內(nèi)存。
          6ToArray方法
              
          這個(gè)方法把ArrayList的元素Copy到一個(gè)新的數(shù)組中。


          4
          ArrayList與數(shù)組轉(zhuǎn)換
              1
          ArrayList List = new ArrayList();
          List.Add(1);
          List.Add(2);
          List.Add(3);

          Int32[] values = (Int32[])List.ToArray(typeof(Int32));

              
          2
          ArrayList List = new ArrayList();
          List.Add(1);
          List.Add(2);
          List.Add(3);

          Int32[] values = new Int32[List.Count];
          List.CopyTo(values);

              
          上面介紹了兩種從ArrayList轉(zhuǎn)換到數(shù)組的方法

              
          3
          ArrayList List = new ArrayList();
          List.Add(
          string );
          List.Add( 1 );
          //
          往數(shù)組中添加不同類型的元素

          object[] values = List.ToArray(typeof(object)); //
          正確
          string[] values = (string[])List.ToArray(typeof(string)); //
          錯(cuò)誤

          和數(shù)組不一樣,因?yàn)榭梢赞D(zhuǎn)換為Object數(shù)組,所以往ArrayList里面添加不同類型的元素是不會(huì)出錯(cuò)的,但是當(dāng)調(diào)用ArrayList方法的時(shí)候,要么傳遞所有元素都可以正確轉(zhuǎn)型的類型或者Object類型,否則將會(huì)拋出無法轉(zhuǎn)型的異常。


          5ArrayList最佳使用建議

              這一節(jié)我們來討論ArrayList與數(shù)組的差別,以及ArrayList的效率問題
            
          1ArrayListArray的復(fù)雜版本
          ArrayList
          內(nèi)部封裝了一個(gè)Object類型的數(shù)組,從一般的意義來說,它和數(shù)組沒有本質(zhì)的差別,甚至于ArrayList的許多方法,如IndexIndexOfContainsSort等都是在內(nèi)部數(shù)組的基礎(chǔ)上直接調(diào)用Array的對(duì)應(yīng)方法。
            
          2)內(nèi)部的Object類型的影響
             
          對(duì)于一般的引用類型來說,這部分的影響不是很大,但是對(duì)于值類型來說,往ArrayList里面添加和修改元素,都會(huì)引起裝箱和拆箱的操作,頻繁的操作可能會(huì)影響一部分效率。
          但是恰恰對(duì)于大多數(shù)人,多數(shù)的應(yīng)用都是使用值類型的數(shù)組。
          消除這個(gè)影響是沒有辦法的,除非你不用它,否則就要承擔(dān)一部分的效率損失,不過這部分的損失不會(huì)很大。
            
          3)數(shù)組擴(kuò)容
              這是對(duì)ArrayList效率影響比較大的一個(gè)因素。
          每當(dāng)執(zhí)行AddAddRangeInsertInsertRange等添加元素的方法,都會(huì)檢查內(nèi)部數(shù)組的容量是否不夠了,如果是,它就會(huì)以當(dāng)前容量的兩倍來重新構(gòu)建一個(gè)數(shù)組,將舊元素Copy到新數(shù)組中,然后丟棄舊數(shù)組,在這個(gè)臨界點(diǎn)的擴(kuò)容操作,應(yīng)該來說是比較影響效率的。
               
          1:比如,一個(gè)可能有200個(gè)元素的數(shù)據(jù)動(dòng)態(tài)添加到一個(gè)以默認(rèn)16個(gè)元素大小創(chuàng)建的ArrayList中,將會(huì)經(jīng)過:
          16*2*2*2*2 = 256
          四次的擴(kuò)容才會(huì)滿足最終的要求,那么如果一開始就以:
          ArrayList List = new ArrayList( 210 );
          的方式創(chuàng)建ArrayList,不僅會(huì)減少4次數(shù)組創(chuàng)建和Copy的操作,還會(huì)減少內(nèi)存使用。

               
          2:預(yù)計(jì)有30個(gè)元素而創(chuàng)建了一個(gè)ArrayList
          ArrayList List = new ArrayList(30);
          在執(zhí)行過程中,加入了31個(gè)元素,那么數(shù)組會(huì)擴(kuò)充到60個(gè)元素的大小,而這時(shí)候不會(huì)有新的元素再增加進(jìn)來,而且有沒有調(diào)用TrimSize方法,那么就有1次擴(kuò)容的操作,并且浪費(fèi)了29個(gè)元素大小的空間。如果這時(shí)候,用:
          ArrayList List = new ArrayList(40);
          那么一切都解決了。
          所以說,正確的預(yù)估可能的元素,并且在適當(dāng)?shù)臅r(shí)候調(diào)用TrimSize方法是提高ArrayList使用效率的重要途徑。
             
          4)頻繁的調(diào)用IndexOfContains等方法(SortBinarySearch等方法經(jīng)過優(yōu)化,不在此列)引起的效率損失
          首先,我們要明確一點(diǎn),ArrayList是動(dòng)態(tài)數(shù)組,它不包括通過Key或者Value快速訪問的算法,所以實(shí)際上調(diào)用IndexOfContains等方法是執(zhí)行的簡(jiǎn)單的循環(huán)來查找元素,所以頻繁的調(diào)用此類方法并不比你自己寫循環(huán)并且稍作優(yōu)化來的快,如果有這方面的要求,建議使用HashtableSortedList等鍵值對(duì)的集合。
          ArrayList al=new ArrayList();

          al.Add("How");
          al.Add("are");
          al.Add("you!");

          al.Add(100);
          al.Add(200);
          al.Add(300);

          al.Add(1.2);
          al.Add(22.8);

          .........

          //
          第一種遍歷 ArrayList 對(duì)象的方法
          foreach(object o in al)
          {
          Console.Write(o.ToString()+" ");
          }

          //
          第二種遍歷 ArrayList 對(duì)象的方法
          IEnumerator ie=al.GetEnumerator();
          while(ie.MoveNext())
          {
          Console.Write(ie.Curret.ToString()+" ");
          }

          //
          第三種遍歷 ArrayList 對(duì)象的方法
          我忘記了,好象是 利用 ArrayList對(duì)象的一個(gè)屬性,它返回一此對(duì)象中的元素個(gè)數(shù).

          然后在利用索引
          for(int i=0;i<Count;i++)
          {
          Console.Write(al[i].ToString()+" ");
          }

          6、ArrayList與vector的對(duì)比
          Vector 還是ArrayList――哪一個(gè)更好,為什么?
          要回答這個(gè)問題不能一概而論,有時(shí)候使用Vector比較好;有時(shí)是ArrayList,有時(shí)候這兩個(gè)都不是最好的選擇。你別指望能夠獲得一個(gè)簡(jiǎn)單肯定答案,因?yàn)檫@要看你用它們干什么。下面有4個(gè)要考慮的因素:
          l API
          l 同步處理
          l 數(shù)據(jù)增長(zhǎng)性
          l 使用模式
          下面針對(duì)這4個(gè)方面進(jìn)行一一探討
          API
          在 由Ken Arnold等編著的《Java Programming Language》(Addison-Wesley, June 2000)一書中有這樣的描述,Vector類似于ArrayList.。所有從API的角度來看這兩個(gè)類非常相似。但他們之間也還是有一些主要的區(qū)別 的。

          同步性
          Vector是同步的。這個(gè)類中的一些方法保證了Vector中的對(duì)象是線程安全的。而ArrayList則是 異步的,因此ArrayList中的對(duì)象并不是線程安全的。因?yàn)橥降囊髸?huì)影響執(zhí)行的效率,所以如果你不需要線程安全的集合那么使用ArrayList 是一個(gè)很好的選擇,這樣可以避免由于同步帶來的不必要的性能開銷。
          數(shù)據(jù)增長(zhǎng)
          從內(nèi)部實(shí)現(xiàn)機(jī)制來講ArrayList和Vector都是使用 數(shù)組(Array)來控制集合中的對(duì)象。當(dāng)你向這兩種類型中增加元素的時(shí)候,如果元素的數(shù)目超出了內(nèi)部數(shù)組目前的長(zhǎng)度它們都需要擴(kuò)展內(nèi)部數(shù)組的長(zhǎng)度, Vector缺省情況下自動(dòng)增長(zhǎng)原來一倍的數(shù)組長(zhǎng)度,ArrayList是原來的50%,所以最后你獲得的這個(gè)集合所占的空間總是比你實(shí)際需要的要大。所 以如果你要在集合中保存大量的數(shù)據(jù)那么使用Vector有一些優(yōu)勢(shì),因?yàn)槟憧梢酝ㄟ^設(shè)置集合的初始化大小來避免不必要的資源開銷。
          使用模式
          在ArrayList 和Vector中,從一個(gè)指定的位置(通過索引)查找數(shù)據(jù)或是在集合的末尾增加、移除一個(gè)元素所花費(fèi)的時(shí)間是一樣的,這個(gè)時(shí)間我們用O(1)表示。但是, 如果在集合的其他位置增加或移除元素那么花費(fèi)的時(shí)間會(huì)呈線形增長(zhǎng):O(n-i),其中n代表集合中元素的個(gè)數(shù),i代表元素增加或移除元素的索引位置。為什 么會(huì)這樣呢?以為在進(jìn)行上述操作的時(shí)候集合中第i和第i個(gè)元素之后的所有元素都要執(zhí)行位移的操作。這一切意味著什么呢?
          這意味著,你只是查找特定 位置的元素或只在集合的末端增加、移除元素,那么使用Vector或ArrayList都可以。如果是其他操作,你最好選擇其他的集合操作類。比如, LinkList集合類在增加或移除集合中任何位置的元素所花費(fèi)的時(shí)間都是一樣的—O(1),但它在索引一個(gè)元素的使用缺比較慢-O(i),其中i是索引 的位置.使用ArrayList也很容易,因?yàn)槟憧梢院?jiǎn)單的使用索引來代替創(chuàng)建iterator對(duì)象的操作。LinkList也會(huì)為每個(gè)插入的元素創(chuàng)建對(duì) 象,所有你要明白它也會(huì)帶來額外的開銷。
          最后,在《Practical Java》一書中Peter Haggar建議使用一個(gè)簡(jiǎn)單的數(shù)組(Array)來代替Vector或ArrayList。尤其是對(duì)于執(zhí)行效率要求高的程序更應(yīng)如此。因?yàn)槭褂脭?shù)組 (Array)避免了同步、額外的方法調(diào)用和不必要的重新分配空間的操作。

          Feedback

          # re: 數(shù)組與向量(Vector)、ArrayList與vector的對(duì)比 --數(shù)據(jù)結(jié)構(gòu)  回復(fù)  更多評(píng)論   

          2007-09-27 19:31 by 千里冰封
          不會(huì)吧,樓主把C#寫到這里來了?

          # re: 數(shù)組與向量(Vector)、ArrayList與vector的對(duì)比 --數(shù)據(jù)結(jié)構(gòu)  回復(fù)  更多評(píng)論   

          2008-04-09 12:37 by shs
          很好,謝謝!

          # re: 數(shù)組與向量(Vector)、ArrayList與vector的對(duì)比 --數(shù)據(jù)結(jié)構(gòu)  回復(fù)  更多評(píng)論   

          2008-07-16 01:40 by 大青山
          vector里面也有自己的方法:add()和remove(),直接使用vectot和通過向量來控制vector有什么不一樣?

          # re: 數(shù)組與向量(Vector)、ArrayList與vector的對(duì)比 --數(shù)據(jù)結(jié)構(gòu)[未登錄]  回復(fù)  更多評(píng)論   

          2008-11-26 01:08 by java
          ...java與C#不分.....
          我要啦免费统计
          主站蜘蛛池模板: 黄梅县| 弋阳县| 民勤县| 米脂县| 太湖县| 泸水县| 闵行区| 宜黄县| 梧州市| 谷城县| 博兴县| 同江市| 磐石市| 简阳市| 泗水县| 伊宁市| 百色市| 巨鹿县| 青岛市| 比如县| 武乡县| 青川县| 朔州市| 武陟县| 乐至县| 新竹市| 龙游县| 揭西县| 那曲县| 凉山| 武安市| 缙云县| 五常市| 江西省| 奉化市| 吉林省| 平山县| 永昌县| 梁山县| 大名县| 道孚县|