新闻门户网站什么意思初学seo网站推广需要怎么做

java中集合类可以说是最常使用的类之一,因为集合类是java中最基础的数据结构,本专题为对java中集合类的实现细节进行总结和探究,供自己复习与他人探讨用,以下所有内容全基于JDK1.8.0_241。
-------------------------------------------正文--------------------------------------------
先放一张集合类的总体UML图:

从图中我们可以看到最顶端的Collection接口是这张图的基础,几乎所有的类和接口都会继承自Collection接口,那么我们就从这个接口开始讲起,先看一下Collection接口中提供了哪些方法:

所有继承Collection接口的类都应该实现这些声明的方法,其中后三个方法与java8的新特性有关,我目前还没有研究,等过一阵再对java8的新特性进行一个总结。在Collection接口中高度抽象了集合需要具备的行为。包括添加、删减、包含等等。
眼尖的bro可能发现了,这里Collection还继承了一个Iterable接口,Iterable接口只有三个方法:

后两个方法同样是java8中的新特性,暂时不考虑,iterator方法返回一个Iterator迭代器对象,我们再来看一下这个Iterator类:

可以看到,里面包含4个方法,最后一个与java8新特性有关。我相信你在写代码的时候肯定不会使用迭代器,那我们什么时候会用到迭代器对集合进行操作呢?我相信你在实际写循环的时候一定写过如下的代码:

那么这种循环的方式背后元是什么呢?其实编译器会把此种循环编译为如下形式:

哦,原来我在不知不觉中已经使用了迭代器,只不过自己不自知,amazing,那我们来简单看看一看在子类ArrayList中时如何实现Iterable接口的:
public Iterator<E> iterator() {return new Itr();
}private class Itr implements Iterator<E> {int cursor; // index of next element to returnint lastRet = -1; // index of last element returned; -1 if no suchint expectedModCount = modCount;Itr() {}public boolean hasNext() {return cursor != size; //cursor位置是否是末尾}@SuppressWarnings("unchecked")public E next() {checkForComodification(); //如果在Iterator迭代的过程中对ArrayList进行更改,throw new ConcurrentModificationException()int i = cursor;if (i >= size)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[lastRet = i]; //更新lastRet和cursor}public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.remove(lastRet); //调用ArrayList的remove方法cursor = lastRet;lastRet = -1;expectedModCount = modCount; //同时更新expectedModCount} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}@Override@SuppressWarnings("unchecked")public void forEachRemaining(Consumer<? super E> consumer) {Objects.requireNonNull(consumer);final int size = ArrayList.this.size;int i = cursor;if (i >= size) {return;}final Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length) {throw new ConcurrentModificationException();}while (i != size && modCount == expectedModCount) {consumer.accept((E) elementData[i++]);}// update once at end of iteration to reduce heap write trafficcursor = i;lastRet = i - 1;checkForComodification();}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}
}
那么我们为什么需要迭代器呢,传统的for(;;)不能满足我们的需求吗?
在一些场景下确实没有什么差别,不过foreach语法更加简洁一点,更重要的是,迭代器语法更加通用,适合所有的容器类。此外,迭代器表示的是一种关注点分离的思想,将数据的实际组织方式与数据的迭代遍历相分离,是一种常见的设计模式,访问容器元素的代码只需要一个Iterator的引用,不需要关注数据的实际组织方式可使用一致的方式进行访问。像ArrayList这种实现类可能性能提升不明显,但对于LinkedList来说,性能提升很大。
回到第一张图,继承自Collection接口的三个最基本的接口:List、Set和Queue。
List接口
list接口的特点是有序,可重复。

这里面大部分都是和Collection接口中重复的方法,这里挑两个重要的说:
ListIterator方法返回的是List接口所特有的迭代器ListIterator,与刚刚提到的Iterator相比多了几个方法,最大的不同是可以向前迭代了,但基本思路相近,不赘述了。

再看一个Sort方法,此方法传入一个Comparator接口,告知排序方法,就能够对List内的元素进行排序。
Queue接口
先看一下Queue接口的结构

Queue接口仅继承于Collection接口,此接口抽象了队列数据结构的操作方法:
boolean add(E e) :添加元素,如果队列空间不足会抛出IllegalStateException
boolean offer(E e):添加元素,如果队列空间不足会返回false
E remove() :删除队列首元素,与poll不同的地方在于如果队列空,会throws NoSuchElementException
E poll():删除队列首元素
E element():返回队首元素,不改变结构,为空会抛出NoSuchElementException
E peek():返回队首元素,不改变结构,为空会返回null
Set接口
Set接口扩展自Collection,但没有任何新增的方法,不过它有一个要求,即所有实现者必须保证Set的语义约束,即不能包含重复元素。
