本文内容来源于网络,若有错误,敬请指正
java集合的使用总结
Collection 是对象集合, Collection 有两个子接口 List 和 Set,List 可以通过下标 (1,2..) 来取得值,值可以重复,而 Set 只能通过游标来取值,并且值是不能重复的
ArrayList , Vector , LinkedList 是 List 的实现类
ArrayList 是线程不安全的, Vector 是线程安全的,这两个类底层都是由数组实现的
LinkedList 是线程不安全的,底层是由链表实现的
Map 是键值对集合
HashTable 和 HashMap 是 Map 的实现类
HashTable 是线程安全的,不能存储 null 值
HashMap 不是线程安全的,可以存储 null 值
总结一:比较
数组 (Array) ,数组类 (Arrays)
Java 所有“存储及随机访问一连串对象”的做法, array 是最有效率的一种。但缺点是容量固定且无法动态改变。 array 还有一个缺点是,无法判断其中实际存有多少元素, length 只是告诉我们 array 的容量。
Java 中有一个数组类 (Arrays) ,专门用来操作 array 。数组类 (arrays) 中拥有一组 static 函数。equals() :比较两个 array 是否相等。 array 拥有相同元素个数,且所有对应元素两两相等。 fill() :将值填入 array 中。 sort() :用来对 array 进行排序。 binarySearch() :在排好序的 array 中寻找元素。 System.arraycopy() : array 的复制。
若编写程序时不知道究竟需要多少对象,需要在空间不足时自动扩增容量,则需要使用容器类库, array 不适用。
array与ArrayList
array是数组,而arraylist是以数组结构为底层结构实现的集合。二者访问效率都较高,查询数据很方便,删改数据资源占有率较高。
二者的区别是:Arraylist的长度是不固定的,可以随着需求增长,而array数组中的长度必须在定义时确定。再者,array中只能存储基本数据类型,array list中可以储存任意数据。arraylist/linkedlist/vector
这三个集合类都时List接口的实现类,都有这list集合接口的共同特征。是有序的 Collection ,次序是 List 最重要的特点:它保证维护元素特定的顺序。
区别:LinkedList是链表结构的集合,强调索引,对顺序访问进行了优化,向 List 中间插入与删除的开销并不大。随机访问则相对较慢。
arraylist是数组结构的集合,存储空间连续,允许对元素进行快速随机访问,但是向 List 中间插入与移除元素的速度很慢。
linkedList和ArrayList都是非同步的。
vector与array list非常类似,也是数组结构的集合,但是 Vector 是同步的。由 Vector 创建的 Iterator ,虽然和 ArrayList 创建的 Iterator 是同一接口,但是,因为 Vector 是同步的,当一个 Iterator 被创建而且正在被使用,另一个线程改变了 Vector 的状态(例如,添加或删除了一些元素),这时调用 Iterator 的方法时将抛出 ConcurrentModificationException ,因此必须捕获该异常。容器 (Collection) 与 Map 的联系与区别
Collection 类型,每个位置只有一个元素。
Map 类型,持有 key-value 对 (pair) ,像个小型数据库。
Collections 是针对集合类的一个帮助类。提供了一系列静态方法实现对各种集合的搜索、排序、线程完全化等操作。相当于对 Array 进行类似操作的类—— Arrays 。
如,
Collections.max(Collection coll); 取 coll 中最大的元素。
Collections.sort(List list); 对 list 中元素排序
List , Set , Map 将持有对象一律视为 Object 型别。
Collection 、 List 、 Set 、 Map 都是接口,不能实例化。继承自它们的 ArrayList, Vector, HashTable, HashMap 是具象 class ,这些才可被实例化。
vector 容器确切知道它所持有的对象隶属什么型别。 vector 不进行边界检查。
总结二:需要注意的地方
- Collection 只能通过 iterator() 遍历元素,没有 get() 方法来取得某个元素。
- Set 和 Collection 拥有一模一样的接口。但排除掉传入的 Collection 参数重复的元素。
- Map 用 put(k,v) / get(k) ,还可以使用 containsKey()/containsValue() 来检查其中是否含有某个 key/value 。
- HashMap 会利用对象的 hashCode 来快速找到 key 。
哈希码 (hashing) 就是将对象的信息经过一些转变形成一个独一无二的 int 值,这个值存储在一个 array 中。我们都知道所有存储结构中, array 查找速度是最快的。所以,可以加速查找。发生碰撞时,让 array 指向多个 values 。即,数组每个位置上又生成一个梿表。
Map 中元素,可以将 key 序列、 value 序列单独抽取出来。
使用 keySet() 抽取 key 序列,将 map 中的所有 keys 生成一个 Set 。
使用 values() 抽取 value 序列,将 map 中的所有 values 生成一个 Collection 。注:为什么一个生成 Set ,一个生成 Collection ?那是因为, key 总是独一无二的, value 允许重复。
总结三:对于各类几个的选择
从效率角度:
在各种 Lists ,对于需要快速插入,删除元素,应该使用 LinkedList (可用 LinkedList 构造堆栈 stack 、队列 queue ),如果需要快速随机访问元素,应该使用 ArrayList 。最好的做法是以 ArrayList 作为缺省选择。 Vector 总是比 ArrayList 慢,所以要尽量避免使用。
在各种 Sets 中, HashSet 通常优于 HashTree (插入、查找)。只有当需要产生一个经过排序的序列,才用 TreeSet 。 HashTree 存在的唯一理由:能够维护其内元素的排序状态。
在各种 Maps 中 HashMap 用于快速查找。
最后,当元素个数固定,用 Array ,因为 Array 效率是最高的。
所以结论:最常用的是 ArrayList , HashSet , HashMap , Array 。
最后的补充:
如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
要特别注意对哈希表的操作,作为 key 的对象要同时正确复写 equals 方法和 hashCode 方法。
尽量返回接口而非实际的类型,如返回 List 而非 ArrayList ,这样如果以后需要将 ArrayList 换成 LinkedList 时,客户端代码不用改变。这就是针对抽象编程。以上都是基础且非常重要,希望大家掌握。