常用集合类总结(java)

来源:互联网 发布:淘宝上退款多久能到账 编辑:程序博客网 时间:2024/06/06 06:41

package java.util 都在这个包下面

Collection extends Iterable

<1> List(接口)
|---LinkedList(实现类)线程非安全
|---ArrayList(实现类)线程非安全
|---Vector(实现类)线程安全

|----Stack(实现类)


        LinkedList 是一个双向链表,它允许任何符合规则的元素插入甚至包括null,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于ArrayList,它除了有ArrayList的基本操作方法外还额外提供了get,remove,insert方法在LinkedList的首部或尾部。由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。如果想实现同步,可以:List list = Collections.synchronizedList(new LinkedList(...));

扩展知识:链表->

                  单向链表:简单理解就是一个节点记录下一个节点的位置

                  双向链接:一个节点记录前一个节点的位置和后一个节点的位置

链表详细参考文章:https://yq.aliyun.com/articles/48908


      ArrayList是一个动态数组,它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。add 操作以分摊的固定时间运行,也就是说,添加 n 个元素需要 O(n) 时间(由于要考虑到扩容,所以这不只是添加元素会带来分摊固定时间开销那样简单)。ArrayList擅长于随机访问。同时ArrayList是非同步的。


       Vector 和ArrayList类似,但属于强同步类。如果你的程序本身是线程安全的(thread-safe,没有在多个线程之间共享同一个集合/对象),那么使用ArrayList是更好的选择。Vector 是同步(线程安全)

        stack   stack继承自Vector,实现一个后进先出的堆栈(push,pop)。还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空

                   Stack通过五个操作对Vector进行扩展,允许将向量视为堆栈。这个五个操作如下:

            操作                                          说明

empty()

测试堆栈是否为空。

peek()

查看堆栈顶部的对象,但不从堆栈中移除它。

pop()

移除堆栈顶部的对象,并作为此函数的值返回该对象。

push(E item)

把项压入堆栈顶部。

search(Object o)

返回对象在堆栈中的位置,以 1 为基数。



Stack刚创建后是空栈,search方法检测一个元素在堆栈中的位置,如果存入相同的object对象,将返回离栈顶最近元素的位置。(示例代码,例如面试题里面的什么,怎么实现链表的倒转)

       

public static void main(String []args){    Stack stack = new Stack();    stack.push("1");stack.push("2");stack.push("3");    Iterator it = stack.iterator();    while(it.hasNext()){        System.out.print(stack.pop());    }
}
 打印结果: 321

扩容方面总结:

   vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势



<2>Set(接口)

|---HashSet(实现类)

|---TreeSet(实现类)

|---LinkedHashSet(实现类)

注意: List和set继承于collection


Set : 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。  HashSet->无序 : 为快速查找设计的Set。存入HashSet的对象必须定义hashCode(),hashSet底层采用hashMap的来存储,存入hashset的值其实就是存入hashMap的key值,value以一个虚拟值代替<底层数据结构是哈希表>
  TreeSet ->无序: 保存次序的Set,使用它可以从Set中提取有序的序列。<底层数据结构是树结构>  LinkedHashSet ->有序: 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。<底层数据结构是哈希表+链表>
答疑一下,有序和无序是相对存入set的元素而言的,但是存入hashset和treeset,如果是bdca 输出都会变成abcd ,字符会按照ascii码表顺序输出,字符串会按照哈希算法排序,treeset可根据comparator自定义排序


<3>Map(接口)

---HashMap

  • HashMap就是一张hash表,键和值都没有排序。

---LinkedHashMap

  • LinkedHashMap保存了插入时的顺序.

---Hashtable

  • Hashtable是同步的(而HashMap是不同步的)。所以如果在线程安全的环境下应该多使用HashMap,而不是Hashtable,因为Hashtable对同步有额外的开销。

---TreeMap

  • TreeMap以红-黑树结构为基础,键值按顺序排列。

---WeakHashMap

  WeakHashMap 继承于AbstractMap,实现了Map接口。
    和HashMap一样,WeakHashMap 也是一个散列表,它存储的内容也是键值对(key-value)映射,而且键和值都可以是null
不过WeakHashMap的键是“弱键”。在 WeakHashMap 中,当某个键不再正常使用时,会被从WeakHashMap中被自动移除。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。某个键被终止时,它对应的键值对也就从映射中有效地移除了。
    这个“弱键”的原理呢?大致上就是,通过WeakReference和ReferenceQueue实现的。 WeakHashMap的key是“弱键”,即是WeakReference类型的;ReferenceQueue是一个队列,它会保存被GC回收的“弱键”。实现步骤是:
    (01) 新建WeakHashMap,将“键值对”添加到WeakHashMap中。
           实际上,WeakHashMap是通过数组table保存Entry(键值对);每一个Entry实际上是一个单向链表,即Entry是键值对链表。
   (02) 当某“弱键”不再被其它对象引用,并被GC回收时。在GC回收该“弱键”时,这个“弱键”也同时会被添加到ReferenceQueue(queue)队列中。
   (03) 当下一次我们需要操作WeakHashMap时,会先同步table和queue。table中保存了全部的键值对,而queue中保存被GC回收的键值对;同步它们,就是删除table中被GC回收的键值对
   这就是“弱键”如何被自动从WeakHashMap中删除的步骤了。

和HashMap一样,WeakHashMap是不同步的。可以使用 Collections.synchronizedMap 方法来构造同步的 WeakHashMap。

原创粉丝点击