1,java集合体系
2,Colletion集合
子接口有List和Set
(1)List接口:ArrayList,Vector,LinkedList
list是collection接口的子接口,特点是元素有序(是指存取有序,不是元素排列按照某种规则排序)可重复,
A:ArrayList:底层是一个数组开始在初始化的时候是0,但add的时候,默认会变成10,扩容的话,每次扩容是 原来的1.5倍,因为底层是数组,通过下标查询,所以查询会比较快,删除比较慢。
B:Linkedlist:底层是一个双向链表,就是带头结点和尾结点的双向链表,提供了两种插入方式,一个是头插 (linkedfirst)一个是尾插(linkedlast),由于是链表,他比较适合增删改操作。但是查询慢,主要是因为在 查询过程中,由于底层是链表,查询的时候它会从第一个开始一个一个比较,这样会导致很慢。
C:Vector:底层数据结构是数组,查询快,增删慢,实现原理基本和arraylist一样,有点区别的是vector在实现 的时候,方法都加了synchronized锁,这是为了保证在多线程环境下保证其安全性,但就是由于线程是 安全的,效率也会变慢,扩容大小是原来的2倍。
一般情况下,我们也不会使用,而是使用collections工具类的synchronizedLsit方法解决arraylist的线程安全 问题。
(2) Set集合:hashset(子类:LinkedHsahSet),treeset
Set集合的特点是元素不重复无序的。
A:Hashset:源码解析,哈希表结构。而哈希表结构底层依赖:hashCode()和equals()方法。(或者是基于HashMap)
进入add方法
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
看源码可以看出return一个map的put方法,put方法传进来的e,其中value是一个常量PRESENT。
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
首先比较哈希值,如果相同,继续走。比较地址值或者走equals(),如果不同,就直接添加到集合中
按照方法的步骤来说:
先看hashCode()值是否相同,
相同:继续走equals()方法,返回true: 说明元素重复,就不添加,返回false:说明元素不重复,就添加到集合
不同:就直接把元素添加到集合, 如果类没有重写这两个方法,默认使用的Object()。一般来说不同相同。 而String类重写了 hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉。只留下一个。
B:TreeSet:能够对元素按照某种规则进行排序。
排序有两种方式: A:自然排序, B:比较器排序,TreeSet集合的特点:排序和唯一
通过观察TreeSet的add()方法,我们知道最终要看TreeMap的put()方法。
C:LinkedHashSet:底层数据结构由哈希表和链表组成。哈希表保证元素的唯一性,链表保证元素有有序。
3,Map集合:键值对的方式存贮,键唯一,值可重复
子实现类:hashmap(子类:linkedhashmap),treemap,hashtable,
(1)Hashmap:他的底层结构在1.7和1.8有点不一样,1.7的话底层数据结构是一个单链表和数组。1.8之后底层 结构式单量表和数组,但是单链表的长度大于等于八的时候,单链表会向红黑树转化,如果红黑树的节点 树小于等于六的时候,它又会转到单链表。1.7的时候吧,put的时候,是头插,会有个resize的过程,会形成一个 环形链表导致死循环,1.8的时候改成尾插了。一般put的时候,第一次会根据key的值计算hash值,通过hash 值得到元素所在的数组的下标如果已经有其他元素,在这个位置的元素就会以链表的形式存在,新加入放在头部 (1.8是在尾部),如果不存在,就放在数组的该位子上面。
(2)Treemap:TreeMap基于红黑树(Red-Black tree)实现。该映射根据其键的自然顺序进行排序,或者根据 创 建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。TreeMap的本质是R-B Tree(红黑 树),它包含几个重要的成员变量: root, size, comparator。
root 是红黑数的根节点。它是Entry类型,Entry是红黑数的节点,它包含了红黑数的6个基本组成成分: key(键)、value(值)、left(左孩子)、right(右孩子)、parent(父节点)、color(颜色)。Entry节点根据key进行排 序,Entry节点包含的内容为value。 红黑数排序时,根据Entry中的key进行排序;Entry中的key比较大小是 根据比较器comparator来进行判断 的。size是红黑数中节点的个数。
(3)Hashtable:基于哈希表的Map结构的实现,线程安全,内部映射无序,不允许值为null的key和value。
(4) Linkedhashmap:他的hashmap的子实现类,LinkedHashMap可以认为是HashMap+LinkedList,也就 是说,它使用HashMap操作数据结构,也用LinkedList维护插入元素的先后顺序.LinkedHashMap的实现思想就是 多态, 理解LinkedHashMap能帮助我们加深对多态的理解.
4,迭代器 Iterator 是什么?
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序 列 的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
5,Iterator 怎么使用?有什么特点?
Java中的Iterator功能比较简单,并且只能单向移动:
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元 素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
(2) 使用next()获得序列中的下一个元素。
(3) 使用hasNext()检查序列中是否还有元素。
(4) 使用remove()将迭代器新返回的元素删除。
Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也 可以从List中插入和删除元素。
6. Iterator 和 ListIterator 有什么区别?
Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索 引,等等。