1.数组与集合的区别
数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用。
集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用。
2.集合类框架图
3.Collection集合接口
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。jdk不提供此接口的直接实现,它提供更具体的子接口(如Set 和List)实现。
如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
Iterator it = collection.iterator(); // 获得一个迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元素
}
Set中不能包含重复的元素。
List是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式。
接口 实现 历史集合类
接口 | 实现 | 历史集合类 |
---|---|---|
set | HashSet | |
TreeSet | ||
list | ArrayList | Vector |
LinkedList | Stack | |
map | HashMap | Hashtable |
TreeMap | Properties |
4.Interator迭代器接口
boolean | hasNext() 如果仍有元素可以迭代,则返回 true。 |
---|---|
E | next() 返回迭代的下一个元素。 |
void | remove() 从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。 |
5.Set接口
1.是Collection接口的一个子接口
2.不包含重复的元素,不存在e1.equals(e2)为true
3.由于提供的数据结构是数学意义上的集合概念的抽象,因此它需要支持对象的添加、删除、而不需提供随机 访问。Set接口继承Collection接口,所有原始方法都是现成的,没有引入新方法
HashSet类
无序不重复非同步,集合元素可以是null,但只能放入一个null,当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对 象在HashSet中存储位置
TreeSet类
1.有序不重复非同步,不允许为null,是SortedSet接口的唯一实现类,支持两种排序方式,自然排序 和定 制排序,其中自然排序为默认的排序方式。定制排序使用Comparator接口,实现 int compare(T o1,T o2)方法
2.判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0
3.自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小,将元素按照升序排列
总结:
1.TreeSet 是二差树实现的,Treeset中的数据是自动排好序的,不允许放入null值。
2.HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复。
3.HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的 String对象hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例
4.HashSet和TreeSet是Set的两个典型实现,HashSet的性能总比TreeSet好(添加,查询操作),因为TreeSet需要额外的红黑树算法来维护集合元素的次序
5.HashSet还有一个子类LinkedHashSet,对于普通的插入,删除操作,LinkedHashSet比HashSet要慢一点点,这是因为维护链表所带来的开销。不过遍历集合时,LinkedHashSet就非常块
6.List接口
1.是collection的子接口
2.代表有序的集合 ,集合中每个元素都有其对应的顺序索引
3.允许使用重复元素,通过索引来访问指定位置的集合元素
ListIterator接口:
ListIterator接口是Iterator的子接口,提供了专门操作List的方法。
ListIterator接口新增的方法:
1)boolean hasPrevious():返回该迭代器关联的集合是否还有上一个元素。
2)Object previous():返回该迭代器的上一个元素。
3)void add():在指定位置插入一个元素。根据上面的三个方法和解释,不难发现ListIterator新增加了向前迭代的功能,而且ListIterator还可以通过add方法向List集合中添加元素。
ArrayList和Vector:
ArrayList和Vector类都是基于数组实现的List类,ArrayList和Vector类封装了一个动态在分配的Object[ ]数组。
每个ArrayList或Vector对象有一个capacity属性,该属性表示他们所封装的数组的长度,当想ArrayList或Vector中添加元素时,它们的capacity会自动增加。
对于通常编程中,程序员无须关心ArrayList或Vector的capacity属性。但如果向ArrayList集合或Vector集合中添加大量元素时,可使用ensureCapacity方法一次性的增加capacity。这样可以提高性能。
ArrayList和Vector在用法上几乎完全相同(Vector是古老的集合,JDK1.0就存在了),但ArrayList集合是线程不安全的,当多条线程访问同一个集合时,如果有超过一条线程修改了ArrayList集合,则程序必须手动保证该集合的同步性。而Vector集合则是线程安全的。无须程序保证集合的同步性。所以Vector的性能比ArrayList的性能低。
LinkedList实现类:
它实现了List接口,还实现了Deque接口,Deque接口是Queue接口的子接口,它代表一个双向队列。
7.Map接口
Map接口不是 Collection 接口的继承,Map<K,V> Map集合类用于存储元素对(称作键和值),其中每个键映射到一个值,该接口描述了从不重复的键到值的映射。
Map子类
1).HashTable,底层是哈希表数据结构,不可以存入null键和null值,线程同步,JDK1.0效率低
2).HashMap,底层是哈希表数据结构,可以存入null键和null值,不同步,JDK1.2效率高
3).TreeMap,底层是二叉树数据结构,线程不同步,可以用于Map键排序.
Map集合转为Set集合
1).Set<K>keySet(),将所有的键存入Set集合,再使用迭代器获取value值
2).Set<Map.Entry<K,V>>entrySet(), entrySet()方法返回一个实现Map.Entry接口的Set集合,集合中存放的是键 值对应关系,该关系是Map.Entry型
Map.Entry是Map接口的内部接口,getKey(): 返回条目的关键字,getValue(): 返回条目的值
HashMap 和 TreeMap
1.在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按顺序遍历键,那么TreeMap 会更好
2.根据集合大小,先把元素添加到 HashMap,再把这种映射转换成一个用于有序键遍历的 TreeMap 可能更快
3. 使用HashMap 要求添加的键类明确定义了 hashCode() 实现。有了TreeMap 实现,添加到映射的元素一定是可排序的
4.为了优化 HashMap 空间的使用,您可以调优初始容量和负载因子。这个TreeMap 没有调优选项,因为该树总处于平衡状态
8. 总结
Set子接口:无序,不允许重复,检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变
HashSet:以哈希表的形式存放元素,插入删除速度很快
TreeSet: 二叉树
List子接口:有序,可以有重复元素,和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变
ArrayList:动态数组
LinkedList:链表、双向队列、堆栈
Vector是一种老的动态数组,线程同步的,效率低
Map接口:键值对、键不重复
HashTable,底层是哈希表数据结构,不可以存入null键和null值,线程同步,JDK1.0效率低
HashMap,底层是哈希表数据结构,可以存入null键和null值,不同步,JDK1.2效率高
TreeMap,底层是二叉树数据结构,线程不同步,可以用于Map键排序