zoukankan      html  css  js  c++  java
  • 各种List、Map、Set的比較

    前言:Java中用不同的数据结构(哈希表/动态数组/平衡树/链表)实现了不同的集合接口(List/Map/Set)。大多数情况下,集合类被用于不须要线程安全地环境,所以后来的集合实现都没有再採用同步以便执行更快,而之前老的实现如Vector、HashSet则保留了同步特性。

    List:List接口继承自Collection,是有序的(有序与排序不同,有序是指集合中元素保持插入时的顺序,而排序是指按对象大小安排位置)。


    1.【动态数组】ArrayList:擅长随机元素訪问。使用数组存储。ArrayList会比Vector快,他是非同步的,假设设计涉及到多线程。还是用Vector比較好一些。

    优势在于动态的增长数组,很适合初始时总长度未知的情况下使用。实现了可变大小的数组。它同意全部元素,包含null。 每一个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断加入新元素而自己主动添加。可是增长算法并未定义。当须要插入大量元素时,在插入前能够调用ensureCapacity方法来添加ArrayList的容量以提高插入效率;
    2.【动态数组】Vector:其方法都是同步的。除非须要同步的场合。否则基本被其同门师弟ArrayList替代;
    3.【动态数组】Stack:实现了先入后出(FILO)。这样的特性比較特殊,所以在新的集合库中没有直接相应的类。
    4.【链表】LinkedList:双向列表存储,优势在于在中间位置插入和删除操作,速度是最快的。LinkedList实现了List接口,同意null元素。

    此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque);

    Map:Map中的键是绝对不能反复的,实现了Map接口的集合类能够用来高速检索数据。建议使用不可变类作为Map的key(原因见下HashSet表述)。
    1.【哈希表】HashMap:Map中訪问速度最快。是Hashtable的轻量级实现(非线程安全的实现)。他们都完毕了Map接口。主要差别在于HashMap同意空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。同意将null作为一个entry的key或者value,而Hashtable不同意。

    把Hashtable的contains方法去掉了,改成containsvalue和containsKey。由于contains方法easy让人引起误解。

    当我们将键值对传递给 put ()方法时,它调用键对象的 hashCode ()方法来计算 hashcode,让后找到 bucket 位置来储存值对象。

    当获取对象时。通过键对象的 equals ()方法找到正确的键值对。然后返回值对象。
    2.【哈希表】LinkedHashMap:是有序的(即依照插入顺序排列);
    3.【哈希表】IdentityHashMap:
    4.【哈希表】Hashtable:其方法都是同步的,除非须要同步的场合,否则基本被其同门师弟HashMap替代。继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。其方法是Synchronize的,而HashMap不是。在多个线程訪问Hashtable时。不须要自己为它的方法实现同步,而HashMap 就必须为之提供外同步(假设是ArrayList:List lst = Collections.synchronizedList(new ArrayList());假设是HashMap:Map map = Collections.synchronizedMap(new HashMap());)。

    Hashtable和HashMap採用的hash/rehash算法都大概一样。所以性能不会有非常大的差异;
    5.【平衡树】TreeMap:实现了SortedMap。能够提供排序功能。
    6.SortedMap:由TreeMap实现。元素是排序的。其键值对按键的升序排列,依照Map.Entry中key来排序。

    Set:Set和Collection最大的差别是Set不能有反复的元素,而Collection能够。

    建议使用不可变类作为set的元素(原因见下HashSet表述)。


    1.【哈希表】HashSet:Set中訪问速度最快。原则上Set不能有反复的元素,但如果HashSet插入不同元素后,又将2个元素改成相同值也能够(这样的属于没有定义行为。即Set的各个实现能够自行处理这样的情况,能够报异常也能够如HashSet般不闻不问,可是这样的没有定义行为应尽量避免,而避免的方法就是使得插入的元素不可改动,也即使得元素为不可变类,Map也有相同问题)。
    2.【哈希表】LinkedHashSet:是有序的(即依照插入顺序排列);
    3.【平衡树】TreeSet:实现了SortedSet。能够提供排序功能;
    4.SortedSet:由TreeSet实现,元素是排序的,按升序排列的(排序与有序不同。见上述)。

    小结:对于查找、插入和删除,哈希表的平均性能优于平衡树,由于对于查找而言后者要在平衡树的分支中不断查找,对于增删后者要不断调整数结构以维持平衡。

    =========================================================

    Iterator和ListIterator的差别​:
    - ListIterator有add()方法。能够向List中加入对象,而Iterator不能;
    - ListIterator和Iterator都有hasNext()和next()方法,能够实现顺序向后遍历。可是ListIterator有hasPrevious()和previous()方法,能够实现逆向(顺序向前)遍历。

    Iterator就不能够;
    - ListIterator能够定位当前的索引位置,nextIndex()和previousIndex()能够实现。Iterator没有此功能。
    - 都可实现删除对象,可是ListIterator能够实现对象的改动,set()方法能够实现。

    Iierator仅能遍历,不能改动。

    Hashmap怎样同步。有两种选择:​
    - 使用Collections.synchronizedMap(..)来同步HashMap。
    - 使用ConcurrentHashMap,首选是使用ConcurrentHashMap,这是由于我们不须要锁定整个对象。以及通过ConcurrentHashMap分区地图来获得锁。​

    IdentityHashMap和HashMap的差别​:
    - 在HashMap中假设两个元素是相等的。则key1.equals(key2)​;
    - 在IdentityHashMap中假设两个元素是相等的,则key1 == key2。

    小结:Iterator是全部集合间的粘合剂,长处在于被全部集合类型所支持,能够编写通用的代码。

    =========================================================

    选择不同数据结构的关注点:查询、插入、删除、元素的唯一性、元素的次序、元素是否有必须定义的方法、线程安全性

  • 相关阅读:
    hadoop_并行写操作思路_2
    hadoop_并行写操作思路
    Hadoop_Block的几种状态_DataNode
    KMP算法_读书笔记
    德才论
    换个格式输出整数
    继续(3n+1)猜想
    害死人不偿命的(3n+1)猜想
    c# number求和的三种方式
    c# 中的协变和逆变
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7077987.html
Copyright © 2011-2022 走看看