您的位置:首页 > 编程语言 > Java开发

java容器类分析:Collection,List,ArrayList,LinkedList深入解读

2018-03-06 21:37 519 查看

1、 Iterable 与 Iterator

Iterable 是个接口,实现此接口使集合对象可以通过迭代器遍历自身元素.

public interface Iterable<T>

修饰符和返回值方法名描述
Iterator<T>iterator()返回一个内部元素为T类型的迭代器
default voidforEach(Consumer<? super T> action)对内部元素进行遍历,并对元素进行指定的操作
default Spliterator<T>spliterator()创建并返回一个可分割迭代器
第一个接口iterator()是jdk1.5引入的,需要子类实现一个内部迭代器Iterator遍历元素。

后两个接口是JDK1.8后新添加的,forEach(Consumer action)是为了方便遍历操作集合内的元素,spliterator()则提供了一个可以并行遍历元素的迭代器,以适应现在cpu多核时代并行遍历的需求.

其中我们可以看下default修饰符,这也是Java 8后新出现的,我们知道,如果我们给一个接口新添加一个方法,那么所有他的具体子类都必须实现此方法,为了能给接口拓展新功能,而又不必每个子类都要实现此方法,Java 8新加了default关键字,被其修饰的方法可以不必由子类实现,并且由dafault修饰的方法在接口中有方法体,这打破了Java之前对接口方法的规范.

Iterator 为迭代器类,用于遍历容器。

public interface Iterator<E>

修饰符和返回值方法名描述
booleanhasNext()判断迭代器所指元素是否为最后一个
Enext()下一个元素
default Voidremove()移除迭代器只想的当前元素
default VoidforEachRemaining(Consumer<? super E> action)遍历迭代器指向元素后面的所有元素
AbstartList中实现了Iterator类作为List内部的迭代器,用于访问内部元素,其代码如下:

1 private class Itr implements Iterator<E> {
2         /**
3          * Index of element to be returned by subsequent call to next.
4          */
5         int cursor = 0;
6
7         /**
8          * Index of element returned by most recent call to next or
9          * previous.  Reset to -1 if this element is deleted by a call
10          * to remove.
11          */
12         int lastRet = -1;
13
14         /**
15          * The modCount value that the iterator believes that the backing
16          * List should have.  If this expectation is violated, the iterator
17          * has detected concurrent modification.
18          */
19         int expectedModCount = modCount;
20
21         public boolean hasNext() {
22             return cursor != size();
23         }
24
25         public E next() {
26             checkForComodification();
27             try {
28                 int i = cursor;
29                 E next = get(i);
30                 lastRet = i;
31                 cursor = i + 1;
32                 return next;
33             } catch (IndexOutOfBoundsException e) {
34                 checkForComodification();
35                 throw new NoSuchElementException();
36             }
37         }
38
39         public void remove() {
40             if (lastRet < 0)
41                 throw new IllegalStateException();
42             checkForComodification();
43
44             try {
45                 AbstractList.this.remove(lastRet);
46                 if (lastRet < cursor)
47                     cursor--;
48                 lastRet = -1;
49                 expectedModCount = modCount;
50             } catch (IndexOutOfBoundsException e) {
51                 throw new ConcurrentModificationException();
52             }
53         }
54
55         final void checkForComodification() {
56             if (modCount != expectedModCount)
57                 throw new ConcurrentModificationException();
58         }
59     }
60


View Code

2、Collection

Collection 是容器类的接口,里面可以存放很多Elements,很多容器都实现了该接口。

public interface Collection<E> extends Iterable<E>

修饰符和返回值方法名描述
intsize()判断容器的大小
booleanisEmpty()判空
booleancontains(Object o)是否包含某元素
Object[]toArray()转化为数组
<T> T[]toArray(T[] a)将容器中所有元素拷贝到a中,如果a不够大,则拷贝到返回的数组中。(见AbstactCollection中实现)
booleanadd(E e)添加元素
booleanremove(Object o)移除容器中第一个出现Object对象,如果Object为null,则移除第一个出现的null。如果没有Object对象返回false
booleancontainsAll(Collection<?> c)包含c中所有元素
booleanaddAll(Collection<? extends E> c);将c中所有元素添加到容器中
booleanremoveAll(Collection<?> c)如果容器中包含c中的元素,删除。(调用remove(Object))
default booleanremoveIf(Predicate<? super E> filter)移除所有符合条件的元素(JDK1.8中引入)
booleanretainAll(Collection<?> c)保留在c中出现的元素,其它全部移除
booleanclear() 
booleanequals(Object o)与o中所有元素都相等则相等
int hashCode()c1.equals(c2) 那么他们的hashCode()一定相等,反之不成立
default Spliterator<E>spliterator()在所有元素之上创建一个Spliterator
default Stream<E>stream() 
default Stream<E>parallelStream() 
上述很多函数的实现可以参考 AbstactList中的实现。

public E set(int index, E element) {
checkElementIndex(index);
Node<E> x = node(index);    //node(Int i) 遍历LinkedList查找第i个Node
E oldVal = x.item;
x.item = element;
return oldVal;
}


View Code
public void add(int index, E element):在链表的index位置添加一个节点
这里还有众多的插入删除等函数,其主要思想还是对链表的操作(插入删除等),详情阅读源码。

3.5 ArrayList 与LinkedList 性能比较

两种List的存储结构决定了两者的性能:ArrayList以数组形式存储,LinkedList以链表形式存储

ArrayList是以数组的形式存储的,所以他的遍历很快,可以根据index很快找到对应元素。但是,ArrayList的插入和删除操作较慢,如果需要在数组中插入一个元素或者删除一个元素较麻烦。

LinkedList的索引操作较慢(需要遍历列表才能找到对应索引元素),但是它的插入和删除操作效率高(只需要控制前后指针就能实现插入和删除)。

参考:

https://www.cnblogs.com/bushi/p/6647006.html

https://www.jianshu.com/p/047e33fdefd2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐