Java Collection-new:Core Java 9

Collection(集合)、
List(列表-有序序列)、Set(集-无重复)、Queue(队列-先进先出)
Vector(同步的ArrayList) Stack(先进后出) ArrayList(动态数组、高效随机访问) LinkedList(高效插入、删除)
HashSet(HashMap实现) SortedSet(SortedMap实现)
ArrayDeque(循环数组实现的双端队列) PriorityQueue(小顶堆实现的优先队列) LinkedList(链表实现的双端队列)
Map(映射,表)

在这里插入图片描述
​​​​​​​​​​​​在这里插入图片描述
在这里插入图片描述

Collection

iterater size add remove clear contains stream removeIf
splitIterater isEmpty addAll removeAll retainAll containsAll parallelStram foreach

add : 如果添加元素改变了集合,则返回true。如果集合没有发生变化则返回false。
比如,添加时发现元素e已经存在,就不执行添加。
其它如:remove / removeIf / addAll 等返回值为boolean的方法,返回值逻辑同上

Iterable / foreach

所有实现了Iterable接口的类的对象,都可以用foreach遍历

Iterator<T>	iterator()
void	forEach(Consumer<? super T> action)
default Spliterator<T>	spliterator()

Iterator

迭代器,所有实现了Iterable接口的类对象,都可获得自己的迭代器,可以用来迭代访问或者删除所有元素。
remove / next / hasNext
当调用iterater.next()时,指针指向下一位置的元素,并返回这个刚刚越过的元素。
调用iterater.remove()时,会删除掉刚越过的那个元素。如果调用remove之前没有调用next是不合法的,必须越过并返回了要删除的元素,才能对那个元素执行remove操作。

boolean	hasNext()
E	next()
default void	remove()
default void	forEachRemaining(Consumer<? super E> action)

ListIterator

针对List接口提供的迭代器

void add(E e);   // 与Collection不同的是,此方法不返回boolean类型值,因为List(有序序列)允许重复,所以会直接add,不做是否重复的检查
				//  另,此方法当前元素前添加元素,因此,如果刚获得listIterator,没有做任何next()操作,就调用add(e)的情况下,元素e是会添加到序列的头部,而非尾部。
void set(E e);  // 用e取代指针当前指向的元素
void remove();  //必须与next()或者previous()合用
boolean hasPrevious();
E previous();
int nextIndex();  // 返回后续调用next()时返回的元素的位置。
int previousIndex();  

Queue

队列:入队add、出队remove、报数element

Throws Exception : add / remove / element
return special value : offer / poll / peek

队列,通常意义上指的是先进先出的队列,add是指入队到尾部,remove出队则从头部出,element(相当于get)也是访问头部数据。

也有一些特定要求的队列,比如根据某种条件来决定每次出队的元素。例如,要求每次出队的都是当前队列中最矮的那一个人,这种就是优先队列(PriorityQueue)。

PriorityQueue

小顶堆实现的优先队列 。能够确保任意可读的时刻,队列的第一个元素一定是所有元素中最小的。

因为是采用小顶堆实现的,因此队列内的元素并非是逻辑有序的,队列内的元素只是构成了一个小顶堆,能够确保每次出队时,返回的是最小元素。

用迭代器迭代访问时,访问得到的数据的顺序是按照构成的小顶堆的元素顺序。

  • 入队 add( E e) 时,会调整数据构成小顶堆
  • 出队 remove() 时,删除堆顶元素root,再将剩余元素调整成小顶堆,最后返回root。
  • element()时,返回堆顶元素

Deque :双端队列,可代替堆栈

Throws exception : addFirst / addLast removeFirst / removeLast getFirst / getLast
return special value : offerFirst / offerLast pollFirst / pollLast peekFirst / peekLast

Deque是双端队列。入队、出队、访问都是既可在队头、也可在队尾。

  • 先进先出:removeFirst,addLast 或者 addFirst , removeLast
  • 先进后出:removeLast,addLast 或者 addFirst , removeFirst
循环数组:ArrayDeque

有界:有容量限制的双端队列

链表:LinkedList

元素数量没有上限的双端队列

自然有序·随机访问:List

有序:是指遍历时访问元素的顺序同添加元素时的顺序是一致的。而非比较排序后的有序。
因为每个元素添加时都有特定位置。

可以随机访问:因为每个元素的位置都是特定的,因此可以进行特定位置的随机访问,如下:

add(int index, E e) / remove( int index ) / get( int index) …

适合随机访问-RandomAccess:虽然所有List的实现类都可以随机访问,但是实际上只有内部数据结构为数组的类适合随机访问,jdk为这些类提供了一个接口RadomAccess来标记它们。

void add(int i, E e);
void addAll(int i , Collection<? extends E> c);
E get(int i);
ListIterator<E>  listIterator();
ListIterator<E>  listIterator(int i);
void remove(int i);
int indexOf(Object obj);
int lastIndexOf(Object  obj);

快速随机访问:ArrayList

封装了一个动态再分配的对象数组

调用get( int inex)可以实现快速随机访问。

使用ListIterator高效地插入删除:LinkedList

使用链表的唯一理由是尽可能的减少在列表中间插入或者删除元素所付出的代价。

用迭代器对链表做插入删除操作:如果根据需求,可以对链表用listIterator做 add( e) / remove() 操作,那么这种插入删除操作非常高效。

避免所有使用整数索引访问链表元素的方法,包括get(int index) / add( int index, E e) / remove( int index) 等,因为对链表进行随机访问的效率较低。

例如,下面这段代码的效率极低:
for(int i = 0 ; i < linkedList.size() ; i++){
E e = linkedList.get(i);
do something with e;
}
每次get(i)都要从列表的头部重新开始搜索。linkedList对象根本不做任何缓存位置信息的操作。

因此,应该改成用迭代器的方式,如果程序中需要用到索引,可以用ListIterator类的int nextIndex()方法获取。

如果需要对列表进行随机访问,就用数组或者ArrayList,而不要使用链表。

同步的对象数组:Vector

Vector类的所有方法都是同步的,在同步上会耗费大量时间。

无重复元素:Set

Set中不允许有重复元素。

一个应用场景:读取某个文件中的所有单词,然后输出所有不重复的单词的数量(不是每个单词的出现次数)。

散列集:HashSet

无序:遍历时访问元素的顺序,同add时添加元素的顺序是不一致的。

			Set的实现类HashSet和TreeSet都是无序的,但是LinkedHashSet则是有序的。

不重复:equals判断是否已经存在重复元素

HashSet(int initialCapacity) ;  //  initialCapacity是桶数
散列表

数组+链表(桶)

计算散列码(hashCode),余除桶数,算得桶号,如果有散列冲突,则拉链。

性能优化-桶数:通常设置为预计元素个数的75%~150%。
默认值16,因此当确定元素个数远大于16时,应主动设置桶数。以防解决散列冲突,和再散列带来的性能下降。

再散列(rehash):当 元素个数 >= 桶数*装填因子(load factor) 时,会进行再散列。
将增加桶至原来的2倍,并将所有元素重新散列至新的桶中。

自动比较排序集:SortedSet

向SortedSet中添加元素时,会调用相应的Comparable接口方法(或Comparator接口方法)对元素做比较排序,根据比较排序的结果将元素放在合适的位置,使得SortedSet的遍历顺序是一个经过比较排序后的有序序列。

Comparator<? super E> comparator();
E first();     // 返回集中的最小元素(也就是第一个元素)
E last();		// 返回集中的最大元素(也就是最后一个元素)
NavigableSet:
E higher(E value);     // 返回集合中大于value的最小元素,如果没有则返回null
E lower(E value);     // 返回集合中小于value的最大元素,如果没有则返回null
E ceiling(E value);     // 返回集合中大于等于value的最小元素,如果没有则返回null
E floor(E value);     // 返回集合中小于等于value的最大元素,如果没有则返回null
E pollFirst();       // 返回并删除集中的最小元素
E pollLast();		// 返回并删除集中的最大元素
Iterator<E> descendingIterator();  //返回一个按递减顺序遍历集中元素的迭代器
TreeSet

每次向TreeSet中添加元素(add)时,都会先经历比较排序,然后将元素放在合适的位置,因此耗时要比HashSet长。

比较排序:因为需要对元素做比较排序,因此要求元素是Comparable接口的实现类的对象,或者在构造方法中提供一个比较器。
如果添加的元素不符合上述两种情况,则add方法会抛出一个RuntimeException:java.lang.ClassCastException。

不重复:TreeSet检查是否重复是通过Comparable接口或者Comparator接口来实现判断的,如果这两个接口的比较方法返回的是0,则认为元素重复,如果已经存在重复的元素,则add方法将不会对TreeSet做任何更新。这点与HashSet的判断重复的方法不同。

尽管添加元素时需要经历比较排序,TreeSet仍比用链表或数组逐个检查重复元素快很多。

有序Set:LikedHashSet

内置了一个LinkedHashMap

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章