Java:Collection.List接口实现
Java:Collection.List接口实现
List 接口继承了 Collection 接口以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。在“集合框架”中有两种常规的 List 实现:ArrayList 和 LinkedList。需要线程安全,可使用CopyOnWriteArrayList。 1)我们可以将ArrayList看作是能够自动增长容量的数组。从内部实现机制来讲ArrayList和Vector都是使用数组(Array)来控制集合中的对象。当向这两种类型中增加元素的时候,如果元素的数目超出了内部数组目前的长度它们都需要扩展内部数组的长度,Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%。 2)在ArrayList中,从一个指定的位置(通过索引)查找数据或是在集合的末尾增加、移除一个元素所花费的时间是一样的,这个时间用O(1)表示。但是,如果在集合的其他位置增加或移除元素那么花费的时间会呈线形增长:O(n-i),其中n代表集合中元素的个数,i代表元素增加或移除元素的索引位置。这是因为在进行上述操作的时候集合中第i和第i个元素之后的所有元素都要执行位移的操作。这意味着,你只是查找特定位置的元素或只在集合的末端增加、移除元素,那么应该使用ArrayList。如果是其他操作,你最好选择其他的集合操作类,如LinkedList。 3)建议使用ArrayList来代替Vector。尤其是对于执行效率要求高的程序更应如此。因为使用ArrayList避免了同步和重新分配过多空间。 4)利用ArrayList的toArray()可以返回一个(Object)数组。注意,如果调用toArray(new T[0])则可生成相应类型T的数组,这样做可以避免向下转型时抛出异常。 5)Arrays.asList()可以返回一个列表。Arrays.asList()返回的列表不支持remove(),add()等方法。 List<Integer> list=Arrays. list.set(1, 99);//OK list.add(21);//ERROR 当执行add()方法时,会抛出 6)Arrays.asList()中添加的元素不认识孙类型,必须作显示类型参数说明。 List<Snow> snow1=Arrays. List<Snow> snow2=Arrays. List<Snow> snow4=Arrays.<Snow> 显示的声明一个接受Snow类型的List,则通过Arrays.asList()方法可以接受Snow及其子类,但不能接受子类的子类。必须进行显示类型参数说明Arrays.<Snow> 1)LinkedList通过一个双向链接的节点列表实现。 2)对于通过索引访问和更新元素,LinkedList实现的性能开销略大一点,因为访问任意一个索引都要求跨越多个节点-O(i),其中i是索引的位置。插入元素时除了有跨越多个节点的性能开销之外,还要有另外一个开销,即创建节点对象的开销。在优势方面, LinkedList实现的插入和删除操作没有其他开销—O(1),因此,插入-删除开销几乎完全依赖于插入-删除点离集合末尾的远近。 storage.addFirst(v); } } } } } } LinkedList类实现了Queue接口,因此可以直接将LinkedList作为Queue的一种实现。这个可通过将LinkedList向上转型为Queue。 Queue queue= boolean add(E e) 将指定的元素插入此队列(如果立即可行且不会违反容量限制),在成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException。 E element() 获取,但是不移除此队列的头。 boolean offer(E e) 将指定的元素插入此队列(如果立即可行且不会违反容量限制),当使用有容量限制的队列时,此方法通常要优于 add(E),后者可能无法插入元素,而只是抛出一个异常。 E peek() 获取但不移除此队列的头;如果此队列为空,则返回 null。 E poll() 获取并移除此队列的头,如果此队列为空,则返回 null。 E remove() 获取并移除此队列的头。此方法与 poll 唯一的不同在于:此队列为空时将抛出一个异常。 下例通过继承AbstractList,并重写get()和size()方法,实现了一个只读整型List容器。 array= init(); } array[i]=i; } @Override } @Override } AbstractList<Integer> readList= System. } } } 结果: 0,1,2,3,4,5,6,7,8, 1)ArrayList底层采用数组完成,而LinkedList则是以一般的双向链表(double-linked list)完成,其内每个对象除了数据本身外,还有两个引用,分别指向前一个元素和后一个元素。 如果我们经常在List的开始处增加元素,或者在List中进行插入和删除操作,我们应该使用LinkedList,否则的话,使用ArrayList将更加快速。 2)使用两种 List 实现的哪一种取决于特定的需要。如果要支持随机访问,而不必在除尾部的任何位置插入或除去元素,那么,ArrayList 提供了可选的集合。但如果,要频繁的从列表的中间位置添加和除去元素,而只要顺序的访问列表元素,那么,LinkedList 实现更好。 |