android面试-java集合


一、java集合框架

Java的集合框架主要由Collection以及Map两个接口派生出来,
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap

二、Collection

Collection主要由Set、List、Queue三种, 大致共同的方法:add、addAll、clear、contains、containsAll(Collection)、isEmpty()、iterator()迭代器、remove()、retainAll(Collection)交集、size个数、toArray 

     1、Set:

  概念:无法保证顺序,但是能保证只有一个。

          (1) Hashset():通过hash算法来存储集合中的元素,具有比较好的查找、存储的能力。通过hashcode、equals来判断是否相同,规则:如果两个对象通过equals返回true,那么他们的hashcode相同。
          如果hashcode相同,那么会通过链式的结构来存储这个对象,会导致性能下降。

          为什么不用数组?数组的长度固定,索引连续,无法自由增加长度。hashSet是通过hashcode找到对应的位置去查找。

         
          (2) LinkedHashSet:同样的也是通过hashcode来确定元素存储的位置,同时使用链表来存储元素的次序,当遍历元素时,会按照添加的顺序来访问
          
          (3) TreeSet:使用红黑树来存储数据,根据存入值大小来进行排序,因此需要实现equals以及compareTo(0的时候相等)。规则:如果两个对象通过equals相等, 那么他们compareTo的值为0

          总结:Hashset查找存储比较快,LinkedHashset(子接口)遍历的时候由于使用了链表会快一点,TreeSet使用额外的红黑树  来维护次序。

     2、List:

概念: 是一个可重复,但能保证顺序的集合
          List通过equals来判断是否为同一个对象,如果是,那么当使用remove时删除,从前往后对比删除
          List的ListIterator与Set的Iterator对比增加向前迭代的方法,lit.hasPrevoius,lit.previous
          
          (1) ArrayList与Vector对比:
          两个都是List的实现,完全支持List接口的功能,
          都是基于数组实现的List类,允许再分配的Object[]数组,通过initialCapacity来设置数组的长度,ensureCapacity来确定最小的minCapacity。
          Vector与ArrayList对比,Vector是同步的,而ArrayList是不同步,同时当空间不足的时候,Vector增加为原来的一倍,而ArrayList增加为50%
          默认的minCapacity是10

          (2) Stack:是通过Vector实现的Peek、Pop、Push三个方法。

          (3) Arrays工具类里面有一个asList方法,可以将数组转化成List,但是她不是List类的ArrayList,而是Arrays内部类的List

          (4) Linkedlist内部是使用链表实现,插入删除比较出色,实现了Deque接口

     3、Queue集合:

概念:模拟队列的数据结构,队列不允许随机访问队列中的元素
        (1) element(获取但不删除空的时候返回异常)、peek(获取不删除,空的时候返回null) 、add、 offer(与add对比,当添加的时候满了返回false,而add是出现 异常)、、poll(没有时返回null)、remove(空时抛出异常)
         
(2) offer,add区别:
一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。
这时新的 offer 方法就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。 

(3) poll,remove区别:
remove() 和 poll() 方法都是从队列中删除第一个元素。remove() 的行为与 Collection 接口的版本相似, 但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。

(4) peek,element区别:
element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null
     

        (5) PriorityQueue:按从小到大的顺序输出,不允许插入null

        (6) Deque接口和ArrayDeque双端队列,可以使用ArrayDeque来实现栈,ArrayDeque基于数组

     4、Map集合:

概念:保存具有映射关系的数据,key不允许重复,k与v之间存在一对一的关系。
        clear、containsKey、containsValue、entryKey(返回KV组成的set集合)、get、isEmtpy、keySet、put(k,v)、putAll(map)、remove、size、values、
        entry:getKey、getValue、setValue

        (1) HashMap跟Hashtable两个:
        HashMap线程不同步,而Hashtable是线程同步的,两者都是通过equals来判断是否相等,如果相等那么hashcode相等。比如Hashtable通过equals来判断是否相等,如果相等,那么containssValue都会一直返回true
        尽量不要使用可变对象作为key,即使是可变对象也不要去修改他。
               
        (2) LinkedHashMap:与LinkedHashSet一样,内部使用的是链表实现的,但它使用的是双向链表。并且由于是使用链表实现,所以他能保证插入的顺序,但是相比HashMap维护的成本也就高一点
               
        (3) TreeMap:有序的,内部使用comparable或者comparator来比较实现排序

        (4) WeakHashMap:弱引用,会进行回收

        (5) HashMap与HashSet的选择:
        对于HashSet来说是通过hash算法来决定存储的位置,hash表里面储存元素的位置可以称为桶,每一个桶存储一个元素,当出现hash冲突的时候会出现一个桶有多个元素,他们以链表的形式连接,

        capacity:容量     initial capacity:初始容量     size:尺寸     负载因子:size/capacity
        通过构造器制定一个负责极限,较高的负载极限可以降低内存占用,但是增加查询时间的开销,较低的负载极限可以提高查询的性能,但是会占用比较大的内存
               
        (6) Collecion 有一个binarySearch(list,object)通过二分法查找list

        (7) 同步控制:synchronizedXxx方法来解决多线程并发的状况


三、面试常问点:

hashMap:并发时出现问题:

回答思路(参考
1、Map原理
2、hashmap结构、hashcode、桶、链表
3、put、get(equals)
4、rehashing
5、竞争的关系

四、集合源码分析





猜你喜欢

转载自blog.csdn.net/wzhworld/article/details/78325923