<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Thinker

      - long way to go...

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      24 隨筆 :: 0 文章 :: 143 評論 :: 0 Trackbacks
        我們知道ArrayList是基于Array的,所以它擁有Array的優點,適用于按索引取值的場合,但是它不適合插入數據和刪除數據,因為每插入或刪除一次就會產生一次大量數組內容Copy的操作。而LinkedList正好與ArrayList相反,它比較適合與插入刪除操作,不適合于索引取值,因為它不可以像數組一樣根據索引值直接就可以定位元素的地址,而需要從頭至尾一個一個的來數位置。
        那么有沒有一種數據結構既擁有數據索引取值快速的特性,又擁有快速刪除元素的優點呢?當然有,下面我介紹的就是其中的一種方式,我稱之為無序數組(概念可能與數組的概念有些沖突,因為數組本身是有序的),這種數組包裝方法是基于數組的,所以擁有數組快速索引取值的特點;并且在刪除元素的時候并不移動(Copy)數組內部元素,所以刪除元素的時候速度很快。缺點就是損失了數組的有序性,同時因為該數組是無序的,所以沒有必要提供數據中間插入操作,只可以向數據的末尾添加數據。
        這個數據結構的設計是基于效率的,所以它只適合于對數組的按索引取值和隨機刪除元素的效率要求都比較高,同時對數組的有序性(這里的有序性不是指數組元素的排序順序,而是指數組元素的索引順序)沒有任何要求的場合。
         這個數據結構的一個使用示例場合就是隨機取數據。可以用該數組存儲數據源,然后隨機生成一個索引,并將該索引對應的元素remove掉。而且還能保證數據不被重復讀取。
        下面提供的示例代碼抽取了這個數組的最基本功能,很清晰,沒有什么需要解釋的地方。導致數組無序和快速刪除的根源就在于 remove(int index) 方法中,大家自己看吧。
      1 public class NoOrderArray
      2 {
      3   private Object[] values = null;
      4 
      5   private int size = 0;
      6 
      7   /**
      8    * 數組 NoOrderArray 的構造函數。 <br>
      9    * 
     10    * @param capacity int - 數組的初始容量。
     11    */
     12   public NoOrderArray(int capacity)
     13   {
     14     if (capacity < 0)
     15       throw new IllegalArgumentException("Illegal Capacity: " + capacity);
     16 
     17     values = new Object[capacity];
     18   }
     19 
     20   /**
     21    * 數組 NoOrderArray 的構造函數,初始容量為 8.<br>
     22    */
     23   public NoOrderArray()
     24   {
     25     this(10);
     26   }
     27 
     28   /**
     29    * 設定數組的容量大小,使其至少滿足 minCapacity 所指的大小。 <br>
     30    * 
     31    * @param minCapacity int - 新的容量值。
     32    */
     33   public void ensureCapacity(int minCapacity)
     34   {
     35     int oldCapacity = values.length;
     36 
     37     if (minCapacity > oldCapacity)
     38     {
     39       Object[] oldValues = values;
     40 
     41       int newCapacity = (oldCapacity * 3/ 2 + 1;
     42 
     43       if (newCapacity < minCapacity)
     44         newCapacity = minCapacity;
     45 
     46       values = new Object[newCapacity];
     47 
     48       System.arraycopy(oldValues, 0, values, 0, size);
     49     }
     50   }
     51 
     52   /**
     53    * 向數組 NoOrderArray 中添加元素內容。 <br>
     54    * 
     55    * @param value - 添加的內容。
     56    */
     57   public void add(Object value)
     58   {
     59     ensureCapacity(size + 1);
     60 
     61     values[size] = value;
     62 
     63     size ++;
     64   }
     65 
     66   /**
     67    * 清除數組 NoOrderArray 中的全部元素。 <br>
     68    */
     69   public void clear()
     70   {
     71     // 釋放內存
     72     for (int i = 0; i < size; i ++)
     73       values[i] = null;
     74 
     75     size = 0;
     76   }
     77 
     78   /**
     79    * 返回數組 NoOrderArray 中指定索引的元素。 <br>
     80    * 
     81    * @param index int - 索引值。
     82    * 
     83    * @return Object - 對應的元素。
     84    */
     85   public Object get(int index)
     86   {
     87     if (index >= size || index < 0)
     88       throw new IndexOutOfBoundsException("Index out of bounds.");
     89 
     90     return values[index];
     91   }
     92 
     93   /**
     94    * 判斷當前 NoOrderArray 數組是否為空。 <br>
     95    * 
     96    * @return boolean - 如果為空返回 <code>true</code>.
     97    */
     98   public boolean isEmpty()
     99   {
    100     return (size == 0);
    101   }
    102 
    103   /**
    104    * 移除 NoOrderArray 數組中指定位置的元素。 <br>
    105    * 
    106    * @param index int - 索引值。
    107    * 
    108    * @return Object - 被移除的元素。
    109    */
    110   public Object remove(int index)
    111   {
    112     if (index >= size || index < 0)
    113       throw new IndexOutOfBoundsException("Index out of bounds.");
    114 
    115     Object value = values[index];
    116 
    117     if (index != size - 1)
    118     {
    119       // 將數組最后一個值補充到被移除的位置。
    120       values[index] = values[size - 1];
    121     }
    122     values[size - 1] = null; // 防止該位置永久持有對象的引用
    123     size --;
    124 
    125     return value;
    126   }
    127 
    128   /**
    129    * 判斷指定的數據是否在 NoOrderArray 數組中。 <br>
    130    * 
    131    * @param value Object - 需要判斷的數據。
    132    * 
    133    * @return boolean - 如果包含返回 <code>true</code>.
    134    */
    135   public boolean contains(Object value)
    136   {
    137     if (value == null)
    138     {
    139       for (int i = 0; i < size; i ++)
    140         if (values[i] == null)
    141           return true;
    142     }
    143     else
    144     {
    145       for (int i = 0; i < size; i ++)
    146         if (value.equals(values[i]))
    147           return true;
    148     }
    149 
    150     return false;
    151   }
    152 
    153   /**
    154    * 返回當前數組的大小。 <br>
    155    * 
    156    * @return int - 當前數組的大小。
    157    */
    158   public int size()
    159   {
    160     return size;
    161   }
    162 
    163   /*
    164    * (non-Javadoc)
    165    * 
    166    * @see java.lang.Object#toString()
    167    */
    168   public String toString()
    169   {
    170     StringBuffer buffer = new StringBuffer();
    171 
    172     buffer.append('[');
    173 
    174     for (int index = 0; index < size; index ++)
    175     {
    176       Object value = values[index];
    177 
    178       if (index > 0)
    179         buffer.append(',');
    180 
    181       buffer.append(value);
    182     }
    183 
    184     buffer.append(']');
    185 
    186     return buffer.toString();
    187   }
    188 
    189   /**
    190    * @param args
    191    */
    192   public static void main(String[] args)
    193   {
    194     // TODO 自動生成方法存根
    195   }
    196 }


    posted on 2007-08-27 17:18 Long 閱讀(2966) 評論(9)  編輯  收藏 所屬分類: Java

    評論

    # re: 快速隨機訪問和可刪除的數組 2007-08-28 00:21 姜利陽
    不錯!  回復  更多評論
      

    # re: 快速隨機訪問和可刪除的數組 2007-08-28 10:22 dennis
    這個東西不僅僅是無序這樣的缺點,在大規模數據remove的時候將占據大量無效的內存,因為remove方法僅僅將value[size-1]賦給value[index],然后size--,可沒有將value[size-1]設置為null,這個值盡管已經不用且不可訪問,但是將一直占據在內存里直到整個數組被棄用。修改下remove方法:
    public Object remove(int index) {
    if (index >= size || index < 0)
    throw new IndexOutOfBoundsException("Index out of bounds.");

    Object value = values[index];

    if (index != size - 1) {
    // 將數組最后一個值補充到被移除的位置。
    values[index] = values[size - 1];
    values[size - 1] = null; //設置為null
    }

    size--;

    return value;
    }  回復  更多評論
      

    # re: 快速隨機訪問和可刪除的數組 2007-08-28 10:22 dennis
    況且,我認為這個需求一般用哈希表更好點。  回復  更多評論
      

    # re: 快速隨機訪問和可刪除的數組 2007-08-28 10:35 Long
    @dennis
    樓上朋友,
    我曾經考慮過將values[size - 1] = null;但是沒有考慮周全。當時只考慮到values[size - 1] 的值被先前Remove掉的那個元素位置引用,所以沒有必要設置為null。忽視了這個值可能再次被Remove掉而數組仍然持有引用。
    謝謝提醒。

    另外,哈希表的確是一個好東東,不過對于一個頻繁使用的、數據元素超多、哈希值分布不均勻的應用時,太浪費內存空間了。

    問題已修正。
      回復  更多評論
      

    # re: 快速隨機訪問和可刪除的數組 2007-08-30 12:46 JAVA面試題
    同意  回復  更多評論
      

    # re: 快速隨機訪問和可刪除的數組 2009-03-16 12:55 sun java 工程師
    不是吧,你的這些操作,ArrayList接口已經幫你全都弄好了。為什么自己再弄一個。

    你說的對,ArrayList插入或刪除一次數據就會產生一次大量數組內容Copy的操作。確實是這樣。

    可是單獨增加一個值,并沒有進行那么復雜的操作,具體請看ArrayList.add(E e)這個方法。

    你的上面的代碼的實現,在ArrayList中已經都有了。好好研究ArrayList吧。
    另外說一點你上面的代碼 remove(int index),你的這個方法已經實現了,但是改變了數組的順序,憑什么把最后一個數據插入到index這個位置。理論上都是順移順序的。  回復  更多評論
      

    # re: 快速隨機訪問和可刪除的數組 2009-03-16 13:00 xx
    @sun java 工程師
    注意是快速隨機訪問和快速可刪除。
    ArrayList無法做到快速可刪除。  回復  更多評論
      

    # re: 快速隨機訪問和可刪除的數組 2009-03-16 13:06 sun java 工程師
    @Long
    if (index != size - 1) { //如果相等怎么辦???
    // 將數組最后一個值補充到被移除的位置。
    values[index] = values[size - 1];
    values[size - 1] = null; //設置為null
    }
    size--;
    可否改成一下代碼
    if (index != size - 1) {
    // 將數組最后一個值補充到被移除的位置。
    values[index] = values[size - 1];
    }
    values[size - 1] = null; //設置為null
    size--;  回復  更多評論
      

    # re: 快速隨機訪問和可刪除的數組 2009-03-16 13:14 sun java 工程師
    @xx
    O(∩_∩)O哈哈~,看來都在看這邊文章,如果不考慮順序的話,按照上面的思路下來,本人建議繼承ArrayList再寫一個方法就OK了
    如:
    public class MyList<E> extends ArrayList<E>{
    public Ojbect removeValue(int index){
    if (index >= size || index < 0)
    throw new IndexOutOfBoundsException("Index out of bounds.");
    Object value = values[index];
    if (index != size - 1) {
    // 將數組最后一個值補充到被移除的位置。
    values[index] = values[size - 1];
    }
    values[size - 1] = null; //設置為null
    size--;
    return value
    }
    }  回復  更多評論
      

    # re: 快速隨機訪問和可刪除的數組 2009-03-16 13:19 Long
    @sun java 工程師
    老兄說的是,
    代碼已修正。

    呵呵,寫這個類的時候沒有繼承自ArrayList的主要原因是為了保持它的接口的簡單性,因為ArrayList的接口中有很多與Array的順序/序號操作的相關,比如add(int,object)等等。  回復  更多評論
      

    主站蜘蛛池模板: 色婷婷综合缴情综免费观看| 人妻无码久久一区二区三区免费| 伊人亚洲综合青草青草久热| 久爱免费观看在线网站| 在线观看亚洲AV每日更新无码| 免费永久看黄在线观看app| 中国videos性高清免费| 久久精品国产亚洲AV久| 国产啪亚洲国产精品无码 | 免费在线观看一区| 亚洲综合视频在线| 免费国产高清视频| 亚洲免费在线观看视频| 免费激情网站国产高清第一页| 亚洲av丰满熟妇在线播放| 日本黄色免费观看| 久久久久久夜精品精品免费啦| 婷婷亚洲综合一区二区| 亚洲黄色在线观看网站| 中文字幕亚洲一区二区三区| 两个人的视频高清在线观看免费| 中文字幕的电影免费网站| 亚洲日韩AV一区二区三区中文| 亚洲国产第一站精品蜜芽| 国产成人精品高清免费| 国产精品视频免费观看| 久久www免费人成精品香蕉| 亚洲色www永久网站| 亚洲美女视频网址| 亚洲精品国产精品乱码不99| 最新69国产成人精品免费视频动漫| 一区二区三区观看免费中文视频在线播放 | 99热在线免费播放| h视频在线观看免费| 亚洲第一街区偷拍街拍| 亚洲精品中文字幕无乱码| 国产亚洲成AV人片在线观黄桃| 在线观看免费精品国产| 亚洲毛片免费视频| 一级毛片在线免费观看| 日本黄色动图免费在线观看|