集合--集合框架中的接口与具体的集合

Java集合框架为不同的 集合定义了大量的接口:
集合有两个基本接口:Collection与Map。
  • Collection中插入元素使用  boolean add(E)  方法;Map中使用  V put(K key,V value)。
  • Collection中读取元素使用  迭代器  访问;Map中使用  V get(K key)。
  • List是有序集合,元素会增加到容器的特定位置。可以采用两种方式访问元素:使用迭代器的访问,或者使用一个整数索引访问。后一种方法称为随机访问,因为可以按照任意的顺序进行访问;当使用迭代器访问时,必须顺序地访问元素。
  • List有两种:ArrayList,LinkList。链表尽管也是有序的,但是随机访问的速度很慢,最好使用迭代器进行访问。
  • ListIterator接口是Iterator的子接口,它定义了一个方法用于在迭代器前增加一个元素:void add(E e)。
  • Set接口等同于Collection接口,不过其方法定义更加严谨。集(Set)的add方法不允许添加重复的元素。只要两个集包含相同的元素就认为它们相等,不要求其中的元素具有相同的顺序。
  • SortedSet,SortedMap接口会提供用于排序的比较器对象,这两个接口定义了可以得到集合子集视图的方法。

链表(LinkedList):
  • 一种可以在任何位置进行高效地插入和删除操作的有序序列。
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable

List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。

此类实现 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。

所有操作都是按照双重链接列表的需要执行的。在列表中编索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。

注意,此实现不是同步的。如果多个线程同时访问一个链接列表,而其中至少一个线程从结构上修改了该列表,则它必须 保持外部同步。(结构修改指添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法来“包装”该列表

  • 在Java中,所有的链表都是双向链表。
  • 虽然数组在连续的存储位置上存放对象的引用,但是链表却将每个对象放在独立的节点中。
  • 链表是一个有序集合,每个对象的位置十分重要。LinkedList.add()方法将对象添加到链表的尾部。但是常常需要将元素添加到中间,由于迭代器是描述集合中的位置的,所以这种依赖于位置的add方法由迭代器负责。LinkedList.add()方法假定添加操作总会改变链表,返回值为void,不是Collection中的boolean 。
  • LinkedList类的listIterator()方法返回一个实现了ListIterator接口的对象。ListIterator接口有两个方法:E previous();boolean hasPrevious();用于反向遍历链表,与next相反。void add(E e)用于在迭代器位置之前增加一个对象。如果链表有n个元素,则有n+1个位置可以添加元素。
public interface ListIterator<E>
extends Iterator<E>
    • add方法依赖于迭代器的位置,而remove方法依赖于迭代器的状态。
    • set方法表示用指定元素代替next/previous返回的最后的元素。
    • 如果迭代器发现它的集合被另一个迭代器修改了,或者被该集合自身方法修改,就会抛出异常。
  • 链表不支持快速地随机访问,如果要查看链表中的第n个元素,就必须从头开始,越过n-1个元素。但是LinkedList类还是提供了一个用来访问特定位置的元素的get(i)方法,但是每次查找时都要从列表的头部开始重新搜索,LinkedList对象根本不做任何缓存位置信息的操作。(get(i)方法做出了优化:如果索引大于size()/2,就从链表的尾部开始搜索)。
  • 使用链表的唯一理由就是尽可能减少在列表中进行插入/删除所付出的代价。
public LinkedList()
构造一个空列表

public LinkedList(Collection<? extends E> c)
构造一个包含指定 collection 中的元素的列表,这些元素按其 collection 的迭代器返回的顺序排列。

public E getFirst()
返回此列表的第一个元素。

public E removeFirst()
移除并返回此列表的第一个元素。

public E removeLast()
移除并返回此列表的最后一个元素。

public boolean contains(Object o)
如果此列表包含指定元素,则返回 true。更确切地讲,当且仅当此列表包含至少一个满足 (o==null ? e==null : o.equals(e)) 的元素 e 时返回 true。

public boolean add(E e)
将指定元素添加到此列表的结尾。

public boolean addAll(Collection<? extends E> c)
添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序。如果指定的 collection 在操作过程中被修改,则此操作的行为是不确定的。(注意,如果指定 collection 就是此列表并且非空,则此操作的行为是不确定的。)

public void clear()
从此列表中移除所有元素。

public E get(int index)
返回此列表中指定位置处的元素。

public void add(int index,
                E element)
在此列表中指定的位置插入指定的元素。移动当前在该位置处的元素(如果有),所有后续元素都向右移(在其索引中添加 1)。

public boolean remove(Object o)
从此列表中移除首次出现的指定元素(如果存在)。如果列表不包含该元素,则不作更改。更确切地讲,移除具有满足 (o==null ? get(i)==null : o.equals(get(i))) 的最低索引 i 的元素(如果存在这样的元素)。如果此列表已包含指定元素(或者此列表由于调用而发生更改),则返回 true。

public E peek()
获取但不移除此列表的头(第一个元素)。

public E poll()
获取并移除此列表的头(第一个元素)

public ListIterator<E> listIterator(int index)
返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始。遵守 List.listIterator(int) 的常规协定。
列表迭代器是快速失败 的:在迭代器创建之后,如果从结构上对列表进行修改,除非通过列表迭代器自身的 remove 或 add 方法,其他任何时间任何方式的修改,列表迭代器都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒将来不确定的时间任意发生不确定行为的风险


散列集(HashSet):
  • 一种没有重复元素的无序集合。
    • 散列表(hash table)是一种可以快速查找到所需要对象的数据结构。散列表为每个对象计算一个整数,称为散列码(hash code)。散列码是由对象的实例域计算产生的一个整数。
    • 在Java中,散列表使用链表数组实现。每个列表称为桶。要想查找表中对象的位置,先要计算它的散列码,然后与桶的总数取余,所得到的结果就是保存这个元素的桶的索引。当然,也会遇到桶被占满的情况,这是不可避免的,这种现象被称为散列冲突。这时候就需要用要查找的对象与该桶中所有的对象进行比较,查看对象是否存在。(类比《算法 》中散列表)
    • 桶数是指用于收集具有相同散列值的桶的数目。如果插入到散列表中的元素过多就会增大冲突,降低性能。如果散列表太满,就要再散列(创建一个桶数更多的表,并将所有的元素插入到这个新表中,然后丢弃原来的表 )。装填因子决定何时对散列表进行再散列,默认为0.75。
    • 散列表可以用于实现几个重要的数据结构,最简单的为Set类型。Set是没有重复元素的元素集合。Set的add()方法首先在集中查找要添加的对象,如果不存在,就将这个对象添加进去。
  • Java提供了HashSet类,它实现了基于散列表的集。可以用add方法添加元素,contains方法已经被重写,用来快速地查看某个元素是否出现在集中。它只在某个桶中查找元素,而不必在集中查找全部元素
  • HashSet的迭代器将依次访问所有的桶。由于散列将元素分散在各个位置上,所以元素的访问顺序几乎是随机的。
public interface Set<E>  extends Collection<E>

一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。
在所有构造方法以及 add、equals 和 hashCode 方法的协定上,Set 接口还加入了其他规定,这些规定超出了从 Collection 接口所继承的内容。出于方便考虑,它还包括了其他继承方法的声明(这些声明的规范已经专门针对 Set 接口进行了修改,但是没有包含任何其他的规定)。

boolean contains(Object o)
如果 set 包含指定的元素,则返回 true。更确切地讲,当且仅当 set 包含满足 (o==null ? e==null : o.equals(e)) 的元素 e 时返回 true。

Iterator<E> iterator()
返回在此 set 中的元素上进行迭代的迭代器。返回的元素没有特定的顺序(除非此 set 是某个提供顺序保证的类的实例)。

boolean add(E e)
如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。更确切地讲,如果此 set 没有包含满足 (e==null ? e2==null : e.equals(e2)) 的元素 e2,则向该 set 中添加指定的元素 e。如果此 set 已经包含该元素,则该调用不改变此 set 并返回 false。结合构造方法上的限制,这就可以确保 set 永远不包含重复的元素。

boolean equals(Object o)
比较指定对象与此 set 的相等性。如果指定的对象也是一个 set,两个 set 的大小相同,并且指定 set 的所有成员都包含在此 set 中(或者,此 set 的所有成员都包含在指定的 set 中也一样),则返回 true。此定义确保了 equals 方法可在不同的 set 接口实现间正常工作。


public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, Serializable

此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
此类为基本操作提供了稳定性能,这些基本操作包括 add、remove、contains 和 size,假定哈希函数将这些元素正确地分布在桶中。对此 set 进行迭代所需的时间与 HashSet 实例的大小(元素的数量)和底层 HashMap 实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。
注意,此实现不是同步的。如果多个线程同时访问一个哈希 set,而其中至少一个线程修改了该 set,那么它必须 保持外部同步。这通常是通过对自然封装该 set 的对象执行同步操作来完成的。如果不存在这样的对象,则 应该使用 Collections.synchronizedSet 方法来“包装” set 。最好在创建时完成这一操作,以防止对该 set 进行意外的不同步访问。

public HashSet()
构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。

public HashSet(Collection<? extends E> c)
构造一个包含指定 collection 中的元素的新 set。使用默认的加载因子 0.75 和足以包含指定 collection 中所有元素的初始容量来创建 HashMap。

public HashSet(int initialCapacity,
              float loadFactor)
构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子。

public HashSet(int initialCapacity)
构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。

public Iterator<E> iterator()
返回对此 set 中元素进行迭代的迭代器。返回元素的顺序并不是特定的。

public boolean add(E e)
如果此 set 中尚未包含指定元素,则添加指定元素。更确切地讲,如果此 set 没有包含满足 (e==null ? e2==null : e.equals(e2)) 的元素 e2,则向此 set 添加指定的元素 e。如果此 set 已包含该元素,则该调用不更改 set 并返回 false。


树集(TreeSet):
  • 树集是一种有序集合
  • 可以以任意顺序将元素插入到集合中。在对集合进行遍历时,每个值将自动按照排序后的顺序呈现。
  • 排序是采用红黑树实现的,每次将元素添加到树中时,都被方法正确的排序位置上。因此,迭代器总是以排好序的顺序进行访问。要使用树集,必须能够比较元素,因此这些元素必须实现Comparable接口,或者构造树集时必须提供一个比较器。
  • 将一个元素添加到树中比添加到散列表中要慢。
public class TreeSet<E>
extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, Serializable

基于 TreeMap 的 NavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法

public TreeSet()
构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。插入该 set 的所有元素都必须实现 Comparable 接口。另外,所有这些元素都必须是可互相比较的:对于 set 中的任意两个元素 e1 和 e2,执行 e1.compareTo(e2) 都不得抛出 ClassCastException。如果用户试图将违反此约束的元素添加到 set(例如,用户试图将字符串元素添加到其元素为整数的 set 中),则 add 调用将抛出 ClassCastException。

public TreeSet(Comparator<? super E> comparator)
构造一个新的空 TreeSet,它根据指定比较器进行排序。插入到该 set 的所有元素都必须能够由指定比较器进行相互比较:对于 set 中的任意两个元素 e1 和 e2,执行 comparator.compare(e1, e2) 都不得抛出 ClassCastException。如果用户试图将违反此约束的元素添加到 set 中,则 add 调用将抛出 ClassCastException。

public TreeSet(SortedSet<E> s)
构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。

public Iterator<E> iterator()
返回在此 set 中的元素上按升序进行迭代的迭代器。

public boolean add(E e)
将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。更确切地讲,如果该 set 不包含满足 (e==null ? e2==null : e.equals(e2)) 的元素 e2,则将指定元素 e 添加到此 set 中。如果此 set 已经包含这样的元素,则该调用不改变此 set 并返回 false。

public NavigableSet<E> subSet(E fromElement,
                              boolean fromInclusive,
                              E toElement,
                              boolean toInclusive)
从接口 NavigableSet 复制的描述
返回此 set 的部分视图,其元素范围从 fromElement 到 toElement。如果 fromElement 和 toElement 相等,则返回的 set 为空,除非 fromExclusive 和 toExclusive 都为 true。返回的 set 受此 set 支持,所以在返回 set 中的更改将反映在此 set 中,反之亦然。返回 set 支持此 set 支持的所有可选 set 操作。
如果试图在返回 set 的范围之外插入元素,则返回的 set 将抛出 IllegalArgumentException。

public SortedSet<E> subSet(E fromElement,
                          E toElement)
从接口 NavigableSet 复制的描述
返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。(如果 fromElement 和 toElement 相等,则返回空的 set)。返回的 set 受此 set 支持,所以在返回 set 中的更改将反映在此 set 中,反之亦然。返回的 set 支持此 set 支持的所有可选 set 操作。
如果试图在返回 set 的范围之外插入元素,则返回的 set 将抛出 IllegalArgumentException。
等效于 subSet(fromElement, true, toElement, false)。

public SortedSet<E> tailSet(E fromElement)
从接口 NavigableSet 复制的描述
返回此 set 的部分视图,其元素大于等于 fromElement。返回的 set 受此 set 支持,所以在返回 set 中的更改将反映在此 set 中,反之亦然。返回的 set 支持此 set 支持的所有可选 set 操作。
如果试图在返回 set 的范围之外插入元素,则返回的 set 将抛出 IllegalArgumentException。
等效于 tailSet(fromElement, true)。

public SortedSet<E> headSet(E toElement)
从接口 NavigableSet 复制的描述
返回此 set 的部分视图,其元素严格小于 toElement。返回的 set 受此 set 支持,所以在返回 set 中的更改将反映在此 set 中,反之亦然。返回的 set 支持此 set 支持的所有可选 set 操作。
如果试图在返回 set 的范围之外插入元素,则返回的 set 将抛出 IllegalArgumentException。



public interface SortedSet<E>
extends Set<E>

进一步提供关于元素的总体排序 的 Set。这些元素使用其自然顺序进行排序,或者根据通常在创建有序 set 时提供的 Comparator 进行排序。该 set 的迭代器将按元素升序遍历 set。提供了一些附加的操作来利用这种排序。(此接口是 SortedMap 的 set 对应接口)。
插入有序 set 的所有元素都必须实现 Comparable 接口(或者被指定的比较器所接受)。另外,所有这些元素都必须是可互相比较的:对于有序 set 中的任意两个元素 e1 和 e2,执行 e1.compareTo(e2)(或 comparator.compare(e1, e2))都不得抛出 ClassCastException。试图违反此限制将导致违反规则的方法或者构造方法调用抛出 ClassCastException

Comparator<? super E> comparator()
返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。

SortedSet<E> subSet(E fromElement,
                    E toElement)
返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。(如果 fromElement 和 toElement 相等,则返回空的 set)。返回的 set 受此 set 支持,所以在返回 set 中的更改将反映在此 set 中,反之亦然。返回的 set 支持此 set 支持的所有可选 set 操作。

SortedSet<E> headSet(E toElement)
返回此 set 的部分视图,其元素严格小于 toElement。返回的 set 受此 set 支持,所以在返回 set 中的更改将反映在此 set 中,反之亦然。返回的 set 支持此 set 支持的所有可选 set 操作。

SortedSet<E> tailSet(E fromElement)
返回此 set 的部分视图,其元素大于等于 fromElement。返回的 set 受此 set 支持,所以在返回 set 中的更改将反映在此 set 中,反之亦然。返回的 set 支持此 set 支持的所有可选 set 操作。


优先级队列(PriorityQueue):
  • 一种允许高效删除最小元素的集合。
  • 优先队列中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索。也就是说,无论何时调用remove方法,总会获得当前对列中的最小元素。然而,优先队列并没有对所有的元素进行排序。如果使用迭代的方式进行处理,并不需要对它们进行排序方法 iterator() 中提供的迭代器不 保证以任何特定的顺序遍历优先级队列中的元素。如果需要按顺序遍历,请考虑使用 Arrays.sort(pq.toArray())
  • 优先队列使用了堆(heap)。堆是一种可以自我调节的二叉树,对树进行添加/删除操作时,可以让最小的元素移动到根,而不必花时间对所有的元素进行排序。
public class PriorityQueueTest {

    public static void main(String[] args) {
         // TODO Auto-generated method stub
         PriorityQueue<String> priorityQueue=new PriorityQueue<>();
        priorityQueue.add("A");priorityQueue.add("F");priorityQueue.add("C");priorityQueue.add("D");priorityQueue.add("E");
         for(String string:priorityQueue){
             System.out.print(string+" ");
         }
         System.out.println();
         Iterator<String> iterator=priorityQueue.iterator();
         while(iterator.hasNext()){
             System.out.print(iterator.next()+" ");
         }
    }
}
输出结果为:
A D C F E
A D C F E
  • 与TreeSet一样,既可以保存实现了Comparable接口的对象,也可以保存在构造器中提供的Comparator对象。
public class PriorityQueue<E>
extends AbstractQueue<E>
implements Serializable

一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。优先级队列不允许使用 null 元素。依靠自然顺序的优先级队列还不允许插入不可比较的对象(这样做可能导致 ClassCastException)。
此队列的头 是按指定排序方式确定的最小 元素。如果多个元素都是最小值,则头是其中一个元素——选择方法是任意的。队列获取操作 poll、remove、peek 和 element 访问处于队列头的元素。
优先级队列是无界的,但是有一个内部容量,控制着用于存储队列元素的数组大小。它通常至少等于队列的大小。随着不断向优先级队列添加元素,其容量会自动增加。无需指定容量增加策略的细节。

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选 方法。 方法 iterator() 中提供的迭代器不 保证以任何特定的顺序遍历优先级队列中的元素。如果需要按顺序遍历,请考虑使用 Arrays.sort(pq.toArray())

public PriorityQueue()
使用默认的初始容量(11)创建一个 PriorityQueue,并根据其自然顺序对元素进行排序。

public PriorityQueue(int initialCapacity)
使用指定的初始容量创建一个 PriorityQueue,并根据其自然顺序对元素进行排序。

public PriorityQueue(int initialCapacity,
                    Comparator<? super E> comparator)
使用指定的初始容量创建一个 PriorityQueue,并根据指定的比较器对元素进行排序。




















































  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值