List是一个继承于Collection的接口,即List是集合中的一种。
List是有序、不唯一的队列,List中的每一个元素都有一个索引;第一个元素的索引值是0,往后的元素的索引值依次+1。和Set不同,List中允许有重复的元素。实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。
ArrayList底层结构是基于动态数组,也是我们最常用的集合。它允许任何符合规则的元素插入甚至包括null。它是非线程安全实现
ArrayList实现了RandomAccess接口(“快速随机访问”),实现这个接口的类在使用for循环遍历效率上更优于Iterator迭代器。
随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作,但只会一点一点的扩容,保证满足最小容量需求即可,以此来保证不浪费资源。
在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量,一步扩容到位(注意,此实现不是同步的。如果多个线程同时访问一个 ArrayList 实例,而其中至少一个线程从结构上修改了列表,那么它必须 保持外部同步。
LinkedList底层结构是基于双向链表。
与ArrayList相比,遍历和随机访问的效率低,因为需要指针前后移动而导致效率低,并且LinkedList多使用iterator或者listIterator迭代器来遍历,ArrayList多使用for循环来遍历;新增和删除的效率高,因为Arraylist需要新增或删除后,剩余的数据需要移动位置,ArrayList是一个动态数组。
由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端,节约一半时间)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。
与ArrayList一样,LinkedList也是非同步的。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:Collections.synchronizedList(new LinkedList(…));
还可以使用concurrent包中对应的类来解决线程安全的问题。
LinkedList不支持RandomAccess快速随机访问,因为它可能会产生二次项。
与ArrayList相似,都是使用数组方式存储数据,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。
Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
Set是一个继承于Collection的接口,即Set是集合的一种。
Set是元素唯一、且没有索引的集合。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样允许null的存在,但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,关于API方面。Set的API和Collection完全一样。实现了Set接口的集合有:HashSet、TreeSet、LinkedHashSet、EnumSet。
Set集合结构:
HashSet是无序(不能保证元素的添加顺序,更不能保证元素的自然顺序),不重复,线程不安全
HashSet堪称查询速度最快的集合,因为其内部是以HashCode结构来实现的。集合元素可以是null,但只能放入一个null。它内部元素的顺序是由哈希码来决定的,所以它不保证set的迭代顺序;特别是它不保证该顺序恒久不变。
HashSet继承于AbstractSet,实现了Set, Cloneable, Serializable接口
TreeSet是保证元素的自然顺序
TreeSet是二叉树(红黑树)实现的,基于TreeMap,生成一个总是处于排序状态的set,内部以TreeMap来实现,不允许放入null值。它是使用元素的自然顺序对元素进行排序,或者根据创建Set时提供的 Comparator 进行排序,具体取决于使用的构造方法。
HashSet内部是哈希表结构,基于Hash算法实现的,其性能优于TreeSet,通常是使用HashSet,我们在需要排序的时候才会使用TreeSet。
LinkedHashSet是保证元素的添加顺序
LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。
Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它key唯一,value不唯一。实现map的集合有:HashMap、HashTable、TreeMap、WeakHashMap。
HashMap是HashTable的轻量级实现(即非线程安全实现),所以HashMap需要外部提供同步,效率可能略高于HashTable,并且允许null键值的存在
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
也是以哈希表数据结构实现的,解决冲突时与HashMap也一样也是采用了散列链表的形式。HashTable继承Dictionary类,实现Map接口。其中Dictionary类是任何可将键映射到相应值的类(如 Hashtable)的抽象父类。每个键和每个值都是一个对象。在任何一个 Dictionary 对象中,每个键至多与一个值相关联。Map是”key-value键值对”接口。 HashTable采用”拉链法”实现哈希表不过性能比HashMap要低。
有序散列表,实现SortedMap接口,底层通过红黑树实现。
谈WeakHashMap前先看一下Java中的引用(强度依次递减)
WeakHashMap是HashMap的改进
以弱键实现的基于哈希表的Map。在 WeakHashMap 中,当某个key不再被正常引用时,将会被GC所回收。更精确地说,对于一个给定的key,其映射的存在并不阻止垃圾回收器对该key的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射中有效地移除,因此,该类的行为与其他的 Map 实现有所不同。null值和null键都被支持。该类具有与HashMap类相似的性能特征,并具有相同的效能参数初始容量和加载因子。像大多数集合类一样,该类是不同步的。
1、List、Set都是继承自Collection接口,Map则不是
2、List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉,(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的,加入Set 的Object必须定义equals()方法 ,另外list支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。)
3、Set和List对比:
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
4、Map适合储存键值对的数据
5、线程安全集合类与非线程安全集合类 :
因篇幅问题不能全部显示,请点此查看更多更全内容