淺談Java集合中Array(數組)的應用

咱們都知道,因爲Array(數組)一般意義上講只是一個單純的線性序列,又基於Native,憑此它的效率從來便號稱Java中最高。因此一般咱們也都認可Java中效率最高的存儲方式就是使用數組。可是,因爲數組初始化後大小固定,索引不能超出下標,缺乏靈活的擴展功能等緣由,使得不少人放棄了數組的使用, 轉而使用Collection,List,Map,Set等接口處理集合操做。 誠然在Java中使用集合類能夠極大的簡化咱們的代碼編寫量。可是,有時明明只是緩存一些線性數據,還恰恰有人要使用HashMap保存,系統爲此付出了沒必要要的內存損耗。若是是一般的程序尚未什麼,當應用在高併發或者加載高內存消耗對象時(如Image圖像)無心義的頻繁使用集合類將極易引起OutOfMemoryException。 咱們很清楚,以List接口實現的集合類中,ArrayList內部運算是基於Array的,因此他繼承了Array的優點,很是適合索引取值和存儲線性數據(Vector雖然也是基於Array的,但毀在大量的synchronized上……因此不少狀況下等於廢了……)。但它不適合插入數據和刪除數據,由於每插入或刪除一次就會產生一次大量數組內容Copy的操做。而LinkedList正好與ArrayList相反,它比較適合與插入刪除操做,不適合於索引取值,由於它不能夠像數組同樣根據索引值直接就能夠定位元素的地址,而須要從頭到尾一個一個的來數位置。 其實這也是固然的,但凡接觸過數據結構的都會知道,任何存儲結構都是有其侷限性的,沒有也不可能有全部方面都完美的存儲方式。咱們所能作的,只是儘量使用特定範圍內最有效的解決方案,而對此什麼解決方法最有效呢? 通常狀況下,考慮到效率與類型檢查等問題,應該儘量使用數組,因此我我的比較推薦的方式就是根據須要基於數組定製集合類。 說到這裏可能不少人以開發週期及穩定、通用性爲藉口而直接使用JDK或第三方集合類(或者COPY代碼|||)。其實就我我的認爲,這有些因噎廢食了,確實有時存儲對象比較複雜,本身的集合類性能沒法保障。但在大多數項目中,這種狀況並不存在,咱們徹底有能力根據需求構造集合以免沒必要要的資源佔用及進行相應優化。而某些人每每只是見Hibernate等框架返回個List便有樣學樣的本身也List和Map到底,乾脆忘了Arrays.asList等方法是爲何而存在的。 原本JDK提供給咱們Arrays.asList方法和Collection.toArray方法就是爲了集合類和數組優點互補之用,以此成爲數組和Collection等集合類間的橋樑,只要有這兩種方法Array和Collection就能夠相互轉換。那麼,咱們有什麼理由枉費能夠利用的資源而不用呢? 事實上,咱們只要基本掌握Arrays類和Reflect這兩個有力的武器,操做數組處理持久對象根本就是張飛吃豆芽——小菜一碟。 下面,我拋磚引玉的寫些代碼舉例: TestBean.java(測試用實體類)   package org.loon.framework.db.test.util; /** *//**  * <p>  * Title: LoonFramework  * </p>  * <p>  * Description:  * </p>  * <p>  * Copyright: Copyright (c) 2007  * </p>  * <p>  * Company: LoonFramework  * </p>  *  * @author chenpeng  * @email:[email]ceponline@yahoo.com.cn[/email]  * @version 0.1  */ public class TestBean ...{     String name;     int id;     public int getId() ...{         return id;     }     public void setId(int id) ...{         this.id = id;     }     public String getName() ...{         return name;     }     public void setName(String name) ...{         this.name = name;     } } ArrayUtil.java(用於Array的增、刪、改、查等操做) package org.loon.framework.db.test.util; import java.io.Serializable; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Random; /** *//**  * <p>  * Title: LoonFramework  * </p>  * <p>  * Description:ArrayUtil,數組操做工具類  * </p>  * <p>  * Copyright: Copyright (c) 2007  * </p>  * <p>  * Company: LoonFramework  * </p>  *  * @author chenpeng  * @email:[email]ceponline@yahoo.com.cn[/email]  * @version 0.1  */ public class ArrayUtil implements Serializable...{     /** *//**      *      */     private static final long serialVersionUID = 8057374625909011982L;     // 緩存數組對象     private Object objArray;     // 數組長度     private int size = 0;     // 緩存數組對象實體類型     private String objType;     final static private Random rand = new Random();     private static ArrayUtil instance = null;         /** *//**      * 直接注入Collection      *      * @param collection      * @return      */     public static ArrayUtil getInstance(Collection collection)...{         return getInstance(collection.toArray());     }     /** *//**      * 直接注入對象數組      *      * @param array      */     public static ArrayUtil getInstance(Object array) ...{         if (instance == null) ...{             instance = new ArrayUtil(array);         }         return instance;     }     /** *//**      * 注入類產生指定大小對象數組      *      * @param clazz      * @param maxSize      */     public static ArrayUtil getInstance(Class clazz, int maxSize) ...{         if (instance == null) ...{             instance = new ArrayUtil(clazz, maxSize);         }         return instance;     }     private ArrayUtil() ...{     }     /** *//**      * 注入對象數組產生指定大小對象數組      *      * @param clazz      * @param maxSize      */     private ArrayUtil(Class clazz, int maxSize) ...{         // 轉爲指定大小對象數組         Object array = (Object[]) Array.newInstance(clazz,                 maxSize);         // 初始化         init(array);     }     /** *//**      * 直接注入對象數組      *      * @param array      */     private ArrayUtil(Object array) ...{         init(array);     }         private void init(Object array)...{         // 檢查是否數組對象         if (!(array instanceof Object[])) ...{             throw new IndexOutOfBoundsException("Not object arrays!");         }         // 緩存數組對象         objArray = array;         // 緩存實體類型         objType = array.getClass().getComponentType().getSimpleName();         // 緩存數組長度         size = Array.getLength(objArray);     }     /** *//**      * 返回指定對象索引位置      *      * @param obj      * @return      */     public int get(Object obj) ...{         // 檢查是否合法對象         checkObject(obj);         Object[] object = (Object[]) objArray;         for (int i = 0; i < size; i++)             if (object[i] == obj) ...{                 return i;             }         return -1;     }     /** *//**      * 返回指定索引位置對象      *      * @param index      * @return      */     public Object get(int index) ...{         checkIndex(index);         return getObjectArray()[index];     }     /** *//**      * 加載對象在指定位置      *      * @param obj      * @param index      */     public void add(Object obj, int index) ...{         // 檢查索引是否越界         checkIndex(index);         // 檢查是否合法對象         checkObject(obj);         Object[] objTemp = (Object[]) objArray;         objTemp[index] = obj;         // copy臨時數組到objArray         System.arraycopy(objTemp, 0, objArray, 0, objTemp.length);     }     /** *//**      * 加載對象      *      * @param obj      */     public void add(Object obj) ...{         // 類型檢查         checkObject(obj);         // 累加         next();         // 臨時緩存舊數組數組         Object[] objTemp = new Object[size];         // 加載對象         objTemp[size - 1] = obj;         // copy         System.arraycopy(objArray, 0, objTemp, 0, Array.getLength(objArray));         // 轉換         objArray = objTemp;     }     /** *//**      * 刪除指定索引位置數組數據      *      * @param index      * @return      */     public Object remove(int index) ...{         // 檢查索引是否越界         checkIndex(index);         Object[] objTemp = (Object[]) objArray;         // 從新構建objArray         int j;         if ((j = size - index - 1) > 0) ...{             System.arraycopy(objTemp, index + 1, objTemp, index, j);         }         // 減小size         back();         return objTemp[index];     }     public boolean contains(Object obj) ...{         Object[] objTemp = (Object[]) objArray;         for (int i = 0; i < size; i++) ...{             if (hash(objTemp[i]) == hash(obj)) ...{                 return true;             }         }         return false;     }         public Object[] sub(int startIndex,int endIndex) ...{         //驗證索引範圍         checkIndex(startIndex);         checkIndex(endIndex);         int over=endIndex-startIndex;         if(over<0)...{             throw new IndexOutOfBoundsException("Index beyond the end of the border!");         }         Object[] objTemp = (Object[]) objArray;         Object[] objs = (Object[]) Array.newInstance(objArray.getClass().getComponentType(),                 over);         for(int i=startIndex;i<endIndex;i++)...{             objs[i-1]=objTemp[i-1];         }         return objs;     }     public void clear() ...{         Object[] objTemp = (Object[]) objArray;         // 清空數據         for (int i = 0; i < size; i++) ...{             objTemp[i] = null;             size = 0;         }     }     /** *//**      * 刪除指定的對象實體      *      * @param obj      * @return      */     public boolean remove(Object obj) ...{         // 檢查是否合法對象         checkObject(obj);         Object[] object = (Object[]) objArray;         for (int i = 0; i < size; i++)             if (object[i] == obj) ...{                 remove(i);                 return true;             }         return false;     }     /** *//**      * 混淆數組元素      *      * @return      */     public void mixElements() ...{         mixElements(objArray);     }     /** *//**      * 檢查數組內元素是否爲空      *      * @return      */     public boolean isEmpty() ...{         return (size == 0);     }     /** *//**      * 轉爲list      *      * @return      */     public List getList() ...{         return Arrays.asList((Object[]) objArray);     }     /** *//**      * 減小size      *      */     private void back() ...{         size--;     }     /** *//**      * 增長size      *      */     private void next() ...{         size++;     }     /** *//**      * 檢查索引是否溢出      *      * @param index      */     private void checkIndex(int index) ...{         if (index >= size || index < 0) ...{             throw new IndexOutOfBoundsException("Index " + index                     + " out of bounds!");         }     }     /** *//**      * 檢查對象類型      *      * @param obj      */     private void checkObject(Object obj) ...{         if (obj instanceof Object[]) ...{             throw new IndexOutOfBoundsException("Not loading arrays!");         }         String type;         if (!objType.equals(type = obj.getClass().getSimpleName())) ...{             throw new IndexOutOfBoundsException("Not this " + type                     + " type of loading!");         }     }     /** *//**      * 擴充數組對象      *      * @param obj      * @param i      * @param flag      * @return      */     static public Object expand(Object obj, int i, boolean flag) ...{         int j = Array.getLength(obj);         Object obj1 = Array.newInstance(obj.getClass().getComponentType(), j                 + i);         System.arraycopy(obj, 0, obj1, flag ? 0 : i, j);         return obj1;     }     /** *//**      * 擴充數組對象      *      * @param obj      * @param i      * @param flag      * @return      */     static public Object expand(Object obj, int i) ...{         return expand(obj, i, true);     }     /** *//**      * 隨機返回數組內容      *      * @param obj      */     static public void mixElements(Object obj) ...{         int i = Array.getLength(obj);         for (int k = 0; k < i; k++) ...{             int j = getRandom(k, i - 1);             Object obj1 = Array.get(obj, j);             Array.set(obj, j, Array.get(obj, k));             Array.set(obj, k, obj1);         }     }     static public Random getRandomObject() ...{         return rand;     }     static public int getRandom(int i, int j) ...{         return i + rand.nextInt((j - i) + 1);     }     private int hash(Object obj) ...{         int h = obj.hashCode();         h += ~(h << 9);         h ^= (h >>> 14);         h += (h << 4);         h ^= (h >>> 10);         return h;     }     public int hashCode() ...{         return hash(objArray.getClass());     }     public int size() ...{         return size;     }     /** *//**      * 反回當前數組對象      *      * @return      */     public Object[] getObjectArray() ...{         return (Object[]) objArray;     }     public static void main(String[] args) ...{         /**//*TestBean[] tb = new TestBean[3];         for (int i = 0; i < tb.length; i++) {             tb[i] = new TestBean();             tb[i].setName("name" + i);             tb[i].setId(i);         }         //直接載入已有數組對象         ArrayUtil arrayUtil = ArrayUtil.getInstance(tb);         TestBean tb1 = new TestBean();         // arrayUtil.add(tb[0]);         arrayUtil.remove(tb[0]);         // arrayUtil.remove(tb[2]);         System.out.println(arrayUtil.contains(tb1));         System.out.println(((TestBean) arrayUtil.get(0)).getName());         System.out.println(arrayUtil.size());         // 打亂數組         arrayUtil.mixElements();         for (int i = 0; i < arrayUtil.size(); i++) {             System.out.println(((TestBean) arrayUtil.get(i)).getName());         }*/         //生成TestBean的數組實例,初始容量爲5         ArrayUtil arrayUtil = ArrayUtil.getInstance(TestBean.class,5);         TestBean t = new TestBean();         t.setName("test");         //在數組載入t的實例         arrayUtil.add(t,0);         TestBean t1 = new TestBean();         t1.setName("test1");         arrayUtil.add(t1,1);         arrayUtil.add(t,2);         arrayUtil.add(t,3);         arrayUtil.add(t,4);         //會自動增長數組容量         arrayUtil.add(t);         //顯示索引5數據         System.out.println(((TestBean)arrayUtil.get(5)).getName());         //截取索引1-3,顯示1數據         System.out.println(((TestBean)arrayUtil.sub(1, 3)[1]).getName());     } } 經過例子咱們能夠發現,只是簡單的幾行代碼,就令Array發揮出咱們須要藉助他人集合類才能完成的功能。而這些,卻原本是咱們也能夠輕易作到的。 因此本人在此呼籲,堅持儘可能使用數組,從我作起,從每一個項目作起~~~
相關文章
相關標籤/搜索