浅谈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发挥出咱们须要借助他人集合类才能完成的功能。而这些,却原本是咱们也能够轻易作到的。 因此本人在此呼吁,坚持尽可能使用数组,从我作起,从每一个项目作起~~~
相关文章
相关标签/搜索