贏在執行

          這個世界上只有兩樣東西愈分享愈多,那就是智慧與愛。

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            17 Posts :: 11 Stories :: 13 Comments :: 0 Trackbacks

          1 、什么是 ArrayList
          ????ArrayList 就是傳說中的動態數組,用 MSDN 中的說法,就是 Array 的復雜版本,它提供了如下一些好處:

          • 動態的增加和減少元素
          • 實現了 ICollection IList 接口
          • 靈活的設置數組的大小


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

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

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

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

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

          ****

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

          ?

          Hashtable ArrayList 關于線程安全性的使用方法類似。

          ****

          3 Count 屬性和 Capacity 屬性
          ????Count
          屬性是目前 ArrayList 包含的元素的數量,這個屬性是只讀的。
          Capacity
          屬性是目前 ArrayList 能夠包含的最大數量,可以手動的設置這個屬性,但是當設置為小于 Count 值的時候會引發一個異常。

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

          ????
          另外,還有幾個類似的方法:
          Clear
          方法用于清除現有所有的元素
          Contains
          方法用來查找某個對象在不在列表之中

          ????
          其他的我就不一一累贅了,大家可以查看 MSDN ,上面講的更仔細
          5 TrimSize 方法
          ????
          這個方法用于將 ArrayList 固定到實際元素的大小,當動態數組元素確定不在添加的時候,可以調用這個方法來釋放空余的內存。
          6 ToArray 方法
          ????
          這個方法把 ArrayList 的元素 Copy 到一個新的數組中。


          4
          ArrayList 與數組轉換
          ???? 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 轉換到數組的方法

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

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

          和數組不一樣,因為可以轉換為 Object 數組,所以往 ArrayList 里面添加不同類型的元素是不會出錯的,但是當調用 ArrayList 方法的時候,要么傳遞所有元素都可以正確轉型的類型或者 Object 類型,否則將會拋出無法轉型的異常。


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

          ?????
          2 :預計有 30 個元素而創建了一個 ArrayList
          ArrayList?List?=?new?ArrayList(30);
          在執行過程中,加入了 31 個元素,那么數組會擴充到 60 個元素的大小,而這時候不會有新的元素再增加進來,而且有沒有調用 TrimSize 方法,那么就有 1 次擴容的操作,并且浪費了 29 個元素大小的空間。如果這時候,用:
          ArrayList?List?=?new?ArrayList(40);
          那么一切都解決了。
          所以說,正確的預估可能的元素,并且在適當的時候調用 TrimSize 方法是提高 ArrayList 使用效率的重要途徑。
          ???
          4 )頻繁的調用 IndexOf Contains 等方法( Sort BinarySearch 等方法經過優化,不在此列)引起的效率損失
          首先,我們要明確一點, ArrayList 是動態數組,它不包括通過 Key 或者 Value 快速訪問的算法,所以實際上調用 IndexOf Contains 等方法是執行的簡單的循環來查找元素,所以頻繁的調用此類方法并不比你自己寫循環并且稍作優化來的快,如果有這方面的要求,建議使用 Hashtable SortedList 等鍵值對的集合。
          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? 對象的方法
          foreach(object?o?in?al)
          {
          Console.Write(o.ToString()+"?");
          }

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

          //
          第三種遍歷 ?ArrayList? 對象的方法
          我忘記了 , 好象是 ? 利用 ?ArrayList 對象的一個屬性 , 它返回一此對象中的元素個數 .

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

          posted on 2007-03-16 00:28 飛雪(leo) 閱讀(571) 評論(0)  編輯  收藏 所屬分類: JAVA基礎專區

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 武平县| 体育| 清新县| 淄博市| 丹江口市| 镇远县| 邓州市| 晋城| 福建省| 灵武市| 桦川县| 崇仁县| 桓仁| 安平县| 秀山| 南涧| 甘肃省| 惠东县| 赣州市| 石景山区| 青河县| 平果县| 获嘉县| 太谷县| 宜良县| 三门峡市| 阜阳市| 呼图壁县| 宜春市| 陇川县| 栾川县| 桓仁| 晋江市| 清镇市| 健康| 抚州市| 南康市| 东兰县| 中江县| 乐业县| 安乡县|