集合

集合

线程安全: Vector,HashTable

非线程安全:ArrayList,HashMap,LinkedList,TreeMap,HashSet,TreeSet

Collection接口

Collection是最基本的集合接口,它不提供直接的实现,如List和Set都是继承Collection接口的。

List接口(有序)(可重复)

List接口为Collection直接接口。List 所代表的是有序的 Collection,即它用某种特定的插入顺序来维护元素顺序。用户可以对列表中每个元素的插入位置进行精确地控制,同时可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。实现 List 接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

ArrayList

ArrayList是一个动态数组,允许任何符合规则的元素插入甚至null。每一个ArrayList都有一个初始容量(10),该容量代表了数组大小。随着容器中的元素不断增加。在每次像容器中增加元素的同时都会进行容量检查,当快溢出时就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容而浪费时间、效率。

LinkedList

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

LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在 List 中进行插入和删除操作。

与 ArrayList 一样,LinkedList 也是非同步的。如果多个线程同时访问一个 List,则必须自己实现访问同步。一种解决方法是在创建 List 时构造一个同步的 List:List list =Collections.synchronizedList(new LinkedList(…));

Vector

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

Stack

Stack继承自Vactor,实现先进后出。Stack提供额外的方法使得Vactor得以被当作堆栈使用。其中push和pop方法,还有peek方法得到栈顶元素,empty测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

Set接口(HashSet无序)(不可重复)

**Set是一种不包括重复元素的Collection。**它维持自己的内部排序,所以随机访问没有任何意义。与List一样,Set可以插入null,但是仅有一个。由于Set接口的特殊性,所有传入Set集合的元素都必须不同,同时要注意任何可变对象,如果对集合中元素进行操作时,导致Set集合中有两个相同的元素,则必定会产生,某些问题。实现Set接口的集合有:EnumSet,HashSet,TreeSet。

EnumSet

是枚举的专用 Set。所有的元素都是枚举类型。

HashSet

HashSet 堪称查询速度最快的集合,因为其内部是以 HashCode 来实现的。它内部元素的顺序是由哈希码来决定的,所以它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。

TreeSet

基于 TreeMap,生成一个总是处于排序状态的 set,内部以 TreeMap 来实现。它是使用元素的自然顺序对元素进行排序,或者根据创建 Set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

Map

Map 与 List、Set 接口不同,它是由一系列键值对组成的集合,提供了 key 到 Value 的映射。同时它也没有继承 Collection。在 Map 中它保证了 key 与 value 之间的一一对应关系。也就是说一个 key 对应一个 value,所以它不能存在相同的 key 值,当然 value 值可以相同。实现 map 的有:HashMap、TreeMap、HashTable、Properties、EnumMap。

HashMap

以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的。

TreeMap

键以某种排序规则排序,内部以 red-black(红-黑)树数据结构实现,实现了 SortedMap 接口。

HashTable

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

Queue

队列,它主要分为两大类,一类是阻塞式队列,队列满了以后再插入元素则会抛出异常,主要包括 ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。另一种队列则是双端队列,支持在头、尾两端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。

异同点

  1. Vector 和 ArrayList

    不考虑线程安全因素,一般用线程不安全的ArrayList效率比较高。

    如果在集合中使用数据量较大的数据,用Vector有一定优势。

    根据时间复杂度判断,查找指定位置的数据,用Vector和ArrayList都可以,而如果移动一个指定位置的数据花费的时间为 0(n-i)n 为总长度,这个时候就应该考虑到使用 LinkList。

    ArrayList 和 Vector 是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢,Vector 由于使用了 synchronized 方法(线程安全)所以性能上比 ArrayList 要差

  2. ArrayList 和 LinkedList

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

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

    对于新增和删除操作 add 和 remove,LinedList 比较占优势,因为 ArrayList 要移动数据。(若是单个数据还是使用ArrayList,批量使用LinkedList)

  3. HashMap 和 TreeMap

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

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

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

  4. HashTable 和 HashMap

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

    同步性:HashTable 是线程安全的,也就是说是同步的,而 HashMap 是线程序不安全的,不是同步的 。

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

对集合的选择

  1. 对 List 的选择

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

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

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

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

  2. 对Set的选择

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

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

  3. 对Map的选择

    HashMap 与 HashSet 同样,支持快速查询。但HashTable的速度慢于HashMap,所以 HashMap 在查询方面可以取代 HashTable。
    2、由于 TreeMap 需要维持内部元素的顺序,所以它通常要比 HashMap 和 HashTable 慢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值