Java原生提供的和数据结构有关的类

Java原生提供的和数据结构有关系的类主要由两个接口派生而来:Collection和Map。

本文主讲Collection,Map在稍后新开一篇。


    Collection接口继承了Iterable接口,内部定义了一系列的抽象方法,如:size(), isEmpty(), contains(Object o), iterator(), toArray(), add(E e)等常用方法。

    目前(Java8)Collection家族关系大致如下图,省略了部分我不太熟悉的,之后可能补上。Java原生提供的和数据结构有关的类_第1张图片

     重新画了一张:

Java原生提供的和数据结构有关的类_第2张图片

一、List与Queue家族

    由于这两个接口及其实现类之间关系较为紧密,放在一起讲。这两者之间最主要的不同在于可操作的位置不同,List接口定义的与普通的数组类似,可以对任意位置上的元素进行操作,而Queue则是一个先进先出的队列,只允许对队头和队尾进行操作。先挑几个比较熟悉的实现类和接口总结一下。

    1. ArrayList

    是实现了List接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括null在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小(此类大致上等同于Vector类,除了此类是不同步的)。若需要保持同步,可使用Collections.synchonizedList方法将其封装。

    这个类提供的迭代器是快速失败的。在创建迭代器之后,只能通过迭代器本身对该类进行修改,若直接该类提供的方法来操作内部存储的元素,如添加或移除,那么迭代器就会抛出异常ConcurrentModificationException。

    2. Vector

    Vector类实现了可增长的对象数组,其通过维护capacity和capacityIncrement这两个属性来优化管理内存,每当向量的大小超过capacity时,对象数组会增长capacityIncrement的大小来加长数组。此对象提供的所有方法都使用synchonized关键字修饰了,因此,这个类是同步的。

    其他的特性与ArrayList很相似,这个类提供的iterator同样是快速失败的。

    3.Stack

    Stack是非常经典的数据结构,它提供了后进先出(LIFO)的对象堆栈。它对Vector类进行了拓展,提供了常用的pop和push方法,还有取栈顶的peek方法等。

    API在需要使用栈时,更推荐使用实现Deque接口的ArrayDeque类而不是Stack.

    4. Queue

    数据结构队列的接口,定义了先进先出(FIFO)的队列。定义了remove和poll方法用于移除并获取队列的头,这两个方法的区别在于,当队列为空时,调用remove获取将抛出异常;定义了peek和element方法用于获取但不移除队列的头,当队列为空时,element方法将抛出异常;定义了offer和add方法在队列尾部添加元素,offer方法通常优于add方法,当队列为满时,调用add方法将抛出异常。

    5. Deque(Double ended queue)

    继承Queue,定义了双向队列数据结构的接口,支持两端插入和移除元素。Deque提供了在双端插入、移除、检查元素的方法,与Queue一致,每个操作都提供了两种方法,其中一种在某些情况下会抛出异常,另一种则会抛出特殊值(null或false)。addFirst和offerFirst,removeFirst和pollFirst,getFirst和peekFirst(队尾操作的方法将First替换为Last)。除此之外,Deque继承了Queue的方法,这些方法等同于Deque中定义的对于队尾操作的方法。

    由于一些方法会返回特殊值如null,因此,最好不要在Deque或Queue中存储null。

    6. LinkedList

    这个类实现了Deque接口,可视作一个双向队列,内部通过一个Node内部类实现。通过add和poll方法实现先进先出的队列操作,通过addFirst和addLast方法分别在队头和队尾添加元素,前面的add方法添加在队尾,这个方法内部就是调用的addLst。

    这个类是不同步的,线程不安全。

    

二、Set家族

    List家族是有序的,允许重复的数据集合,而Set则是无需的,不允许重复的数据集合。Set不包含满足e1.equals(e2)这样条件的元素对,同时最多只能有一个null元素。

    当向Set中存储可变对象时需要非常小心,因为元素的改变可能会影响equals方法的结果。

    1. 抽象类AbstractSet

    该类是Set的骨干实现,从而很大程度上减少了Set接口实现的工作量。继承了AbstractCollection抽象类,但没有重写任何的实现,只是添加了equals和hashCode的实现。

    2. 子接口SortedSet

    Set接口的定义是无序的,而SortedSet则提供了一个有序的Set,其内部要么使用compareTo方法进行排序,要么根据在创建有序Set时提供的Comparator进行排序。SortedSet提供的迭代器将根据元素的升序进行迭代。

    所以,放入到SortedSet中的元素必须实现Comparablejiekou或者可以被set中定义的comparator所接受。

    3. 子接口NavigableSort

    这个接口是拓展的SortedSet,提供了一系列“导航”方法,如lower、floor、ceiling和higher分别返回小于、小于等于、大于等于、大于给定元素的所有元素。还定义了pollFirst和pollLast方法,他们返回并移除Set中最小和最大的元素。

    4. 实现类TreeSet

    继承了AbstractSet抽象类,实现了NacigableSort接口。此实现是不同步的。迭代器是快速失败的。

    其内部是通过维护一个NavigableMap来实现的,其内部方法几乎都是通过TreeMap来实现的。关于NavigableMap和TreeMap,在之后写Map相关的内容时再叙述。

你可能感兴趣的:(java)