集合详解

1 Collection接口

Collection是最基本的集合接口,java SDK不允许其他类直接继承Collection接口,只能继承Collection的子接口ListSet接口。
以下是Collection的部分子类层次图。

《集合详解》 Collection的部分子类层次图

1.1 List接口

List是有序的Collection,用户可以准确在任何位置进行插入或删除,只需要根据索引就可以访问其中的元素。

List的遍历方法除了Collection所提供的Interator()方法外,还有自己独有的listInterator()方法,该方法除了可以对元素进行CRUD外,还可以向前向后遍历。

  • ArrayList类

ArrayList实现了可变长的数组,可以保存任何元素,包括null。

每个ArrayList实例都有一个一个容量(Capacity),即集合用于存储元素的个数,容量会随着元素的增加自动增加。在需要插入大量元素时,在插入前可以调用ensureCapacity()方法来增加ArrayList的容量以此来提高效率。

ArrayList是线程不同步的。

  • LinkedList类

LinkedList实现了List接口,允许添加null元素,LinkedList还提供了独有的get、remove、insert方法进行操作,因此LinkedList可以作为stack、queue、deque来使用。

LinkedList也是线程不同步的,如果多个线程同时访问LinkedList,那么需要用户自己实现同步方法。其中一种解决方法是在创建list时构造一个同步list:
List list = Collection.synchronizedList(new LinkedList())

  • Vector类

Vector实现了List接口,和ArrayList类似,只是Vector时线程同步的,当一个Vector正在被使用的时候,其它线程对其操作,将会抛出ConcurrentModificationException异常,因此用户需要对其捕获。

  • Stack类

Stack继承自Vector类,实现了先进后出的堆栈。提供的五个方法使得可以作为栈来使用peek、empty、search、push、pop,其中push、pop方法可以向堆栈中添加和弹出元素,empty方法判断当前堆栈是否为空,peek方法查询当前栈顶元素并返回,search方法查找元素在堆栈中的位置。

1.2 Set接口

Set是一种不包含重复元素的Collection,且最多只有一个null元素。

  • HashSet类
    HashSet类不允许出现重复元素,且是无序的,只能包含一个null元素。

  • TreeSet类
    TreeSet类可以实现集合的排序,在对象向集合中添加时按照某种特定的规则去进行排序。
    当用户没有自己定义排序时,将会按照自然排序。用户若需要自定义排序只需要实现Comparator接口,并重写compare方法。

2 Map接口

Map没有继承Collection ,没有,没有,没有,重要的事需要说三遍。Map是提供key到value的映射,且key不允许重复。以下是常用的Map子类。

《集合详解》 Map常用子类

  • HashTable类

HashTable实现的Map接口,实现了一个key-value的哈希表,任何非空的元素都可以当作key或value,且是同步的。

HashTable通过init capacityload capacity两个参数来调整性能。init capacity是初始化时的集合容量大小,而load capacity是当容量不够时自动添加的比例,缺省的大小为0.75,这样可以实现时间和空间的均衡,增大load capacity时虽然会节省空间但相应的查找时间增加。

由于key对象是通过参列表来查找对应的value值,所以当key保存对象的时候,需要用户自己在该key对象中重写equals和hashCode方法。

  • HashMap类

HashMapHashTable类似,不同之处在与HashMap不是同步的,且可以将null元素作为key或value保存。

  • WeakHashMap类

WeakHashMap是一种改进的HashMap,当key不在被外部所引用时,将会被GC回收。

3 汇总

如果涉及到堆栈,队列,那么应该使用List,对于需要快速进行插入、修改、删除元素,应该优先使用LinkedList,如果只是需要对元素进行查看访问,那么应该使用ArrayList

我们在创建一个对象时,应尽量的去返回该类型的接口,如创建ArrayList返回List,这样的好处就是当我们需要将ArrayList转换成LinkedList时将不需要改变客户端代码。

  • Vector和ArrayList

    • Vector是线程安全的,而ArrayList是线程不安全的, 如果不考虑线程的安全性,那么使用ArrayList的效率会更高。
  • 如果集合中的元素个数大于集合数组中的元素时,Vector每次会增加100%的长度,而ArrayList只会增加50%的长度,当需要插入大量的元素时,使用Vector更高效。

  • 如果要查找某个特定的元素时,VectorArrayList花费的时间是相同的,若当要移动指定元素的位置时,使用LinkedList则更加节省时间。

  • ArrayList和LinkedList

    • ArrayList是基于动态数组实现的数据结构,而LinkedList是基于链表实现的数据结构。

    • 当只是需要随机访问get、set方法时,使用ArrayList更快,因为LinkedList需要移动指针。

    • 当需要对集合数据斤进行增改时,LinkedList更为高效, 因为ArrayList需要移动数据。

当然如果只是对一条数据进行增改时,ArrayList会更快,如果需要对大量数据进行增改时,显然LinkedList还是比ArrayList快。

    原文作者:司鑫
    原文地址: https://www.jianshu.com/p/0fc30bd9c1cd
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞