java学习之集合框架-List与Map

java集合主要划分为五个部分:

List列表、Set集合、Map映射、迭代器(Iterator、Enumeration)、工具类(Arrays、Collections)

主要分为两大类:Collection和Map 


1:Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作和属性。

  • List:List接口通常表示一个列表(数组、队列、链表、栈等),其中的元素可以重复,常用实现类为ArrayList和LinkedList,另外还有不常用的Vector。另外,LinkedList还是实现了Queue接口,因此也可以作为队列使用。

    List是一个有序的队列,每一个元素都有它的索引。第一个元素的索引值是0。

        • ArrayList与LikedList区别

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

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

                 3. 对于添加和删除操作add和remove,一般大家都会说LinkedList要比ArrayList快,因为ArrayList要移动数据。但是实际情况并非这样,对于添加或删除,LinkedList和ArrayList并不能明确说明谁快谁慢


           

          1.对ArrayList和LinkedList而言,在列表中末尾添加一个元素所花的开销是固定的

          2.在ArrayList中间插入一个元素或删除一个元素意味着整个列表中剩余的元素都会移动,而LinkedList的中间插入或删除一个元素的开销是固定的

          3.LinkedList不支持高效的随机访问

           可以这样说:当操作是在一列数据后面添加数据而不是在前面或中间,并且是随机访问其中元素时,使用arrayList会提供比较好的性能;当你操作是在一列数据的前面或中间添加或删除数据,并不是按照顺序访问其中的元素,就应该使用LinkedList了

  • Set: Set接口通常表示一个集合,其中的元素不允许重复(通过hashcode和equals函数保证),常用实现类有HashSet和TreeSet,HashSet是通过Map中的HashMap实现的,而TreeSet是通过Map中的TreeMap实现的。另外,TreeSet还实现了SortedSet接口,因此是有序的集合(集合中的元素要实现Comparable接口,并覆写Compartor函数才行)。

    Set是一个不允许有重复元素的集合。

   



 

 

2:Map是一个映射接口,即key-value键值对。一个key对应一个value。

  Map是一个映射接口,其中的每个元素都是一个key-value键值对,同样抽象类AbstractMap通过适配器模式实现了Map接口中的大部分函数,TreeMap、HashMap、WeakHashMap等实现类都通过继承AbstractMap来实现,另外,不常用的HashTable直接实现了Map接口,它和Vector都是JDK1.0就引入的集合类。



 

HashSet与HashMap

 

  HashSet与HashMap有着相同的实现,但是前者是对后者做了一成包装(HashSet里面有一个HashMap<适配器模式>)。

  HashMap实现了Map接口,允许放入null元素,除该类未实现同步外,其余很HashTable大致相同,跟TreeMap不同。该容器不保证元素顺序,根据需要,该容器可能会对元素重新Hash,元素的顺序也会重新打散,因此,不同时间迭代同一个HashMap的顺序会可能不同。

  根据对冲突的不同处理方式,哈希表有两种实现方式:

    1.开放地址方式(Open addressing)

    2.冲突链表方式是(Seoarate chaining with linked lists)

   Java HashMap采用的是冲突链表方式

 

效率问题:

  从上图容易看出,如果选择合适的哈希函数,put()和get()方法可以在常数时间内完成。但在对HashMap进行迭代时,需要遍历整个table以及后面跟的冲突链表。因此对于迭代比较频繁的场景,不宜将HashMap的初始大小设的过大。
  有两个参数可以影响HashMap的性能:

    初始容量(inital capacity)

    负载系数(load factor)

  初始容量指定了初始table的大小,负载系数用来指定自动扩容的临界值。当entry的数量超过capacity*load_factor时,容器将自动扩容并重新哈希。对于插入元素较多的场景,将初始容量设大可以减少重新哈希的次数。
  将对向放入到HashMap或HashSet中时,有两个方法需要特别关心:hashCode()和equals()。hashCode()方法决定了对象会被放到哪个bucket里,当多个对象的哈希值冲突时,equals()方法决定了这些对象是否是“同一个对象”。所以,如果要将自定义的对象放入到HashMap或HashSet中,需要@Override hashCode()和equals()方法。

 

posted @ 2018-04-02 14:27  没梦想做什么咸鱼  阅读(279)  评论(0)    收藏  举报