thinking in java (十) ----- 集合

我们除了最常用的八种基本类型,String类型,还有集合类Collection,常见的有ArrayList,HahsMap,HashSet,也有不常用的stack,queue,有线程安全的Vector,HashTable,也有线程不安全的LinkedList,TreeMap等。

Collection接口 

这是最基本的集合接口,不提供直接的实现,声明了适用于JAVA集合(只包括Set和List)的通用方法。Map接口并不是Collection接口的子接口,但是它仍然被看作是Collection框架的一部分。

图中可以看到collection接口是由两个子接口Set和List外加一个不是子接口的Map组成,

List:可以通过index来获取元素,它允许元素的重复,ArrayList,LinkedList,Vector实现List接口。

Set:不允许元素的重复,HashSet,TreeSet实现Set接口

Map:使用键值对方式存储,值可以重复,键不可以重复,子接口Hashmap,Hashtable,TreeMap

List接口

List是Collection的直接子接口,也不提供直接的实现,List代表的是有序的Collection,即它用某种特定的插入顺序来维护元素顺序,用户可以对列表中每个元素插入位置进行精确地控制,同时根据元素的索引访问元素。实现List接口的集合主要有ArrayList,LinkedList,Vector,Stack。

  • ArrayList

ArrayList是一个动态数组,也是最常用的集合,继承自AbstractList,,实现List接口。底层基于数组实现容量大小的动态变化,最初的容量默认是10,在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作,他允许任何符合规则的元素插入甚至包括null,同时还实现了RandomAccess,Cloneable,Serializable接口,所以ArrayList是支持快速访问,复制,序列化的。

ArrayList擅长随机访问,同时ArrayList是非同步的。

  • LinkedList

同样实现List接口的LinkedList和ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表,所以它除了ArrayList的基本操作外,还额外提供了get,remove,insert方法在LinkedList首部或者尾部。

由于实现方式不同,LinkedList不能随机访问,他所有的操作都是按照双向链表的需要执行,在列表索引的操作将从开头或者结尾遍历列表,这样做的好处是可以通过较低的代价在List中进行插入和删除操作。

与ArrayList一样,LinkedList也是非同步。如果是非同步问题的话,就涉及到多线程。如果多线程同时访问一个List,则必须自己先实现访问同步,一种方法就是在创建List的时候构造一个同步的List:List list = Collection.synchronizedList(new LinkedList(....))

  • Vector

与ArrayList相似,但是Vector是同步的线程安全,的动态数组,它的操作和ArrayList几乎一样。

  • Stack

几乎没有用过鸭,

Set接口

set是一种不包括重复元素的Collection。实现了

  • EnumSet

枚举的Set,所有的元素都是枚举元素

  • HashSet

HashSet堪称查询速度最快的集合,因为其内部是HashCode来实现的,(需要重写hashcode和equals方法),所以不保证set的迭代顺序,特别是他不保证顺序永恒不变

  • TreeSet

没有用到过。

Map接口

Map和List,set接口不同,他是一些列键值对组成的集合,提供 了K到V的映射,同时他没有继承Collection。在Map中保证了KV的一一对应,所以K不能相同,V可以相同。实现的Map有:hashmap,treemap,hashtable,properties,enumMap

  • HashMap

这个是用的最多的,以hash表数据结构实现,查找对象通过哈希函数计算位置,他是为了快速查询设计的,其内部定义了一个hash数组(Entry[] table),元素会通过hash转换函数将hash地址转换为数组中存放的索引,如果有冲突,就使用散列链表的形式将所有相同hash地址的元素串起来,可能通过查看HashMap.Entry的源码,他是一个单链表结构

  • TreeMap

不会

  • HashTable

也是以哈希数据结构实现的,解决冲突时与HashMap一样采用散列链表的形式,不过性能比hashmap低

Queue

不会

异同点

  • Vector和ArrayList

 1,vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用arraylist效率比较高。 
 2,如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%.如果在集合中使用数据量比较大的数据,用vector有一定的优势。 
 3,如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是0(1),这个时候使用vector和arraylist都可以。而如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用linklist,因为它移动一个指定位置的数据所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。

      ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!

  • ArrayList和linkedList

      1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
      2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
      3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 
      这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。

  • HashMap和TreeMap

       1、HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。HashMap中元素的排列顺序是不固定的)。

      2、  HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。集合框架”提供两种常规的Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。

      3、在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。 这个TreeMap没有调优选项,因为该树总处于平衡状态。

  • HashTable和HashMap

      1、历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现 。

      2、同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的

      3、值:只有HashMap可以让你将空值作为一个表的条目的key或value 。

对集合的选择

  • 对List的选择

     1、对于随机查询与迭代遍历操作,数组比所有的容器都要快。所以在随机访问中一般使用ArrayList

      2、LinkedList使用双向链表对元素的增加和删除提供了非常好的支持,而ArrayList执行增加和删除元素需要进行元素位移。

      3、对于Vector而已,我们一般都是避免使用。

      4、将ArrayList当做首选,毕竟对于集合元素而已我们都是进行遍历,只有当程序的性能因为List的频繁插入和删除而降低时,再考虑LinkedList。

  • 对Set的选择

      1、HashSet由于使用HashCode实现,所以在某种程度上来说它的性能永远比TreeSet要好,尤其是进行增加和查找操作。

      3、虽然TreeSet没有HashSet性能好,但是由于它可以维持元素的排序,所以它还是存在用武之地的。

  • 对Map的选择

     1、HashMap与HashSet同样,支持快速查询。虽然HashTable速度的速度也不慢,但是在HashMap面前还是稍微慢了些,所以HashMap在查询方面可以取代HashTable。

     2、由于TreeMap需要维持内部元素的顺序,所以它通常要比HashMap和HashTable慢。

猜你喜欢

转载自blog.csdn.net/sinat_38430122/article/details/83349175