集合中的方方面面

时间:2021-07-08 15:19:42

ArrayList和Vector LinkedList存储性能和特性

    ArrayList和Vector都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,都是使用数组方式存储数据。一种动态的数组,我们以后可以按位置索引号取出某个元素,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素

   

   ArrayList与Vector的区别,这主要包括两个方面:

   (1)同步性:

         VectorVector由于使用了synchronized方法是线程安全的,也就是说是它的方法之间是线程同步的,性能上较ArrayList差。而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。

 

   Vector与Hashtable是同步的,线程安全的,ArrayList与HashMap是线程不安全的。

   (2)数据增长:

         ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。

 

而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。arrayLIst但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,   

LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList可以被当作堆栈和队列来使用

 

总结:即Vector增长原来的一倍,ArrayList增加

 

如果你经常会使用索引来对容器中的元素进行访问,那么 List 是你的正确的选择。如果你已经知道索引了的话,那么 List 的实现类比如 ArrayList 可以提供更快速的访问,如果经常添加删除元素的,那么肯定要选择LinkedList。

如果你想容器中的元素能够按照它们插入的次序进行有序存储,那么还是 List,因为 List 是一个有序容器,它按照插入顺序进行存储。

如果你想保证插入元素的唯一性,也就是你不想有重复值的出现,那么可以选择一个 Set 的实现类,比如 HashSet、LinkedHashSet 或者 TreeSet。所有 Set 的实现类都遵循了统一约束比如唯一性,而且还提供了额外的特性比如 TreeSet 还是一个 SortedSet,所有存储于 TreeSet 中的元素可以使用 Java 里的 Comparator 或者 Comparable 进行排序。LinkedHashSet 也按照元素的插入顺序对它们进行存储。

如果你以键和值的形式进行数据存储那么Map 是你正确的选择。你可以根据你的后续需要从 Hashtable、HashMap、TreeMap 中进行选择。

 

ArrayList和LinkedList的大致区别:

     1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

     2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

     3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。


   HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。

   HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。

   HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。

   Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。

    最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。

   Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

   

就HashMap与HashTable主要从三方面来说。 一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现 二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的三.值:只有HashMap可以让你将空值作为一个表的条目的key或value

 

,Hashtable缺省的初始大小为101,载入因子为0.75,即如果其中的元素个数超过75个,它就必须增加大小并重新组织元素

 

Collection接口的方法:

booleanadd(Objecto):向集合中加入一个对象的引用

void  clear():删除集合中所有的对象,即不再持有这些对象的引用

booleanisEmpty():判断集合是否为空

boolean  contains(Objecto):判断集合中是否持有特定对象的引用

Iterartor  iterator():返回一个Iterator对象,可以用来遍历集合中的元素

booleanremove(Objecto):从集合中删除一个对象的引用intsize():返回集合中元素的数目

Object[]toArray():返回一个数组,该数组中包括集合中的所有元素

注意:Iterator()和toArray()方法都用于集合的所有的元素,前者返回一个Iterator对象,后者返回一个包含集合中所有元素的数组。

Iterator接口声明了如下方法:

hasNext():判断集合中元素是否遍历完毕,如果没有,就返回truenext():返回下一个元素remove():从集合中删除上一个有next()方法返回的元素


    一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,List中存储的数据是有顺序,并且允许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。

62、List, Set, Map是否继承自Collection接口?

      List,Set是,Map不是


   List与Set都是单列元素的集合,它们有一个功共同的父接口,叫Collection。Set里面不允许有重复的元素,所谓重复,即不能有两个相等()的对象 Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。Set取元素时,没法说取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。

         List: 1.可以允许重复的对象。

        2.可以插入多个null元素(重复元素)。

         3.是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。

         Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key 所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。

4.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。

 

Set:1.不允许重复对象(重复元素)

 2.无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator  或者 Comparable维护了一个排序顺序。

 3. 只允许一个 null 元素

Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。TreeSet类实现了SortedSet接口

 

1.Map不是collection的子接口或者实现类。Map是一个接口。

2.Map 的每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。

3. TreeMap 也通过 Comparator  或者 Comparable维护了一个排序顺序。

4. Map 里你可以拥有随意个 null 值但最多只能有一个null 键。

5.Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。

 

HashSet类按照哈希算法来存取集合中的对象,而不是直接按hashCode值的大小进行存储。例如,"abc" ---> 78,"def"---> 62,"xyz" ---> 

Set的用法:存放的是对象的引用,没有重复对象。

TreeSet:保存次序的Set,底层为树结构。使用它可以从Set中提取有序的序列。LinkedHashSet:具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。

加入Set的元素必须定义equals()方法以确保对象的唯一性。存入HashSet的对象必须定义hashCode()。

 

List的特征是其元素以线性方式存储,集合中可以存放重复对象。

List接口主要实现类包括:

ArrayList():代表长度可以改变得数组。可以对元素进行随机的访问,向ArrayList()中插入与删除元素的速度慢。LinkedList():在实现中采用链表数据结构。插入和删除速度快,访问速度慢。

对于List的随机访问来说,就是只随机来检索位于特定位置的元素。List的get(intindex)方法放回集合中由参数index指定的索引位置的对象,下标从“0”开始。

1、for循环和get()方法:

for(inti=0;iSystem.out.println(list.get(i));

2、使用迭代器(Iterator):

Iteratorit=list.iterator();while(it.hashNext()){System.out.println(it.next());

ListIterator只应该用来由后向前遍历ArrayList。

LinkedList:对顺序访问进行了优化,向List中间插入与删除的开销并不大。随机访问则相对较慢。(使用ArrayList代替。)还具有下列方法:addFirst(),addLast(),getFirst(),getLast(),removeFirst()和removeLast(),,这些方法(没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。

HashMap使用了特殊的值,称为“散列码”(hashcode),来取代对键的缓慢搜索。“散列码”是“相对唯一”用以代表对象的int值,它是通过将该对象的某些信息进行转换而生成的。所有Java对象都能产生散列码,因为hashCode()是定义在基类Object中的方法。

HashMap就是使用对象的hashCode()进行快速查询的。此方法能够显着提高性能。

TreeMap:基于红黑树数据结构的实现。查看“键”或“键值对”时,它们会被排序(次序由Comparabel或Comparator决定)。TreeMap的特点在于,你得到的结果是经过排序的。TreeMap是唯一的带有subMap()方法的Map,它可以返回一个子树。WeakHashMao:弱键(weakkey)Map,Map中使用的对象也被允许释放:这是为解决特殊问题设计的。如果没有map之外的引用指向某个“键”,则此“键”可以被垃圾收集器回收。IdentifyHashMap:使用==代替equals()对“键”作比较的hashmap。专为解决特殊问题而设计。

要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。

 

注意:

1、Collection没有get()方法来取得某个元素。只能通过iterator()遍历元素。

2、Set和Collection拥有一模一样的接口。

3、List可以通过get()方法来一次取出一个元素。

4、一般使用ArrayList。用LinkedList构造堆栈stack、队列queue。

5、Map用put(k,v)/get(k),还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value。HashMap会利用对象的hashCode来快速找到key。

HashSet和 TreeSet 有什么区别:

 

答:TreeSet 中的数据是自动排好序的,不允许放入null

   HashSet 中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。

   HashSet 要求放入的对象必须实现hashCode()方法,放入的对象,是以hashCode作为标示的,而具有相同内容的string对象,hashCode是一样,所以放入的内容不能重复。