*.集合框架:(容器)
Collection 集合层次结构中的根接口:超级接口(单集合)
JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现
List:接口:-存储有序,可重复。
ArrayList:
1.8JDK:默认构造方法,Object数组的长度为0,只是获取了一个引用地址,并没有开辟内存空间。当添加第一个元素时开辟了一个长度为10的Object数组。
1.8JDK以前:默认构造方法,Object数组的长度为10。不管你添加不添加数组都初始为10。
扩容的倍数:是数组.length*1.5:说白了就是1.5倍,数组的本身的长度乘以1.5,每当数组满了以后才扩容。
ArrayList:JDK--->JDK ArrayList:类给我们提供添加,删除,获取,插入,封装了一个Object数组并提供添加,删除,获取,插入方法方便操作。自动扩容,
可以存储多种元素,
ArrayList:低层封装了一个动态扩容的Object数组存储元素。因为基于数组:如果通过下标查找相对速度比较快,删除和插入可能有大量元素移动,
数组需要预分配内存空间所以存在扩容,在扩容期间挪动大量的数组比较耗时效率低。
Vector(向量):
Vector:Vector 类是一个老集合在1.0版本就有,在发布JDK1.2版本是才加入到集合框架中并且实现了List接口所有的方法以外
还保留了一些自己的方法,所有重复功能的方法。
Vector:Vector类也是基于数组,调用默认无参的构造方法,数组的初始容量为10;
扩容的倍数:是数组.length*2:说白了就是1倍,数组的本身的长度乘以2,每当数组满了以后才扩容。
ArrayList与Vector的区别?
1.扩容倍数不同,Vector线程同步的(线程安全),ArrayList线程非同步(线程不安全),
2.相同点:都是List接口的子类,都是泛型类,都是封装了一个动态扩容的Object数组,
3.ArrayList,Vector,LinkedList:都可以存放null值。
泛型:如果不指定默认为Object
LinkedList:
可以存放null值
底层封装了一个双向链表,插入和删除效率高:为什么:不须要移动大量的元素,只需改变元素的前后的引用,不存在扩容,为什么:因为他是动态分配内存空间,就是需要的时候才开辟内存。
缺点:查询效率低:为什么:它必须从头或者从尾一个一个的查找直到找到为止。
线程不同步
//受限制的数据结构
队列:(Queue)
入队的一端称为队尾,出队的一端称为对头:特点:先进先出,后进后出。
使用LinkedList类实现队列:
add(E e);//入队
E poll();//出队
//排队: 只有出队:队头 和入队:队尾
栈:(Stack)
栈也是一种受限制的数据结构:只有一端可以进行操作,特点:先进后出,后进先出。
使用LinkedList类实现栈:(Stack)
list.addFirst(e);//入栈
list.removeFirst();//出栈
Set接口:
HashSet:底层实现是个HashMap,HashMap的底层是个哈希表,需要重写 hashCode与equals:底层是HashMap所以可以存null
TreeSet:底层实现是一个TreeMap,TreeMap底层是个一红黑二叉树,保存的值需要实现Comparable接口,或者在创建集合的时间传入一个自定义比较。否则会出现类型转换异常,如果有自然排序和自定义排序会使用自定义排序。
底层是TreeMap所以不可以存null
LinkedHashSet:最低层是HashMap实现,但是使用LinkedHashMap保存了元素保存的添加的顺序。在HashMap添加时new节点时会到LinkedHashMap中创建并将节点添加到双向链表中
LinkedHashSet---HashSet---LinkedHashMap----HashMap
Iterator<Student> str =list.iterator();
//实现集合框架的统一遍历
//for与Iterator的区别?
//Iterator:是受保护的,在遍历当中如果你去改变集合的元素,终止迭代,并抛出异常,迭代失败
Map<K,V>:双集合的超级接口:K:key(键),V:value(值)
Map:主要用来存储具有映射(对应)关系的对象,所有它有两组值(一组)是键(key):键不可重复(唯一),一组是值(value),如果存储重复的key会覆盖它的值(value)。我们总是可以通过key找到对应的值。
hash表:数组加链表的结合。
哈希表是数据结构唯一个通过数据元素本身的关键值进行存和取,通过关键值计算出元素的哈希码,哈希码就是元素存储的位置。
HashMap:基于哈希表的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。线程不同步,
HashMap:不可存重复的key(键),如果存储重复的key会覆盖它的值(value)。
HashMap的缺点和优点:
基于哈希表的实现。
由于底层是哈希表可以通过哈希码查找相对链表比较快, 删除,插入:只是改变元素的引用,
哈希表是基于数组需要预分配内存空间,存在扩容。在扩容时比较耗时,效率低。
加载因子作用?
用来计算哈希表增加的容量的尺度,怎么计算:加载因子*数组的长度=尺度。当hash表的容量达到这个尺度就会扩容。 加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。
尺度:数组的长度
hash表的扩容:数组是数组长度*2,倍数1
尺度:本身的尺度*2,倍数1
1.8JDK:
调用默认初始化:初始了一个0.75加载因子,数组还是null,添加第一个元素才扩充容量为(16)
扩容:如果hash表元素没有达到尺度但是某个桶的数量超过8个也会自动扩容,
一个桶超过了八个元素且数组的长度超过了64:会将这个桶变为树结构(红黑树)。
HashMap使用:重写hashCode:可以同存储的对象本身的关键属性找到它所存储的位置。
重写equals:根据需求判断对象是否重复。
hashCode与equals尽量保持一致。
HashTable:不能存储null(键和值) Hashtable与HashMap不同:此类是同步的,HashMap不同步。
调用默认构造方法默认初始数组11个长度。加载因子为:0.75.
HashTable与HashMap的相同点和不同点:
相同点: 底层都是哈希表实现。都map的子类,默认加载因子都是:0.75,都存在扩容,都要重写hashCode和equals方法。键都不能重复,
不同点: 1.HashMap可以存键值为(null),HashTable不能存键值为(null)
2.初始容量不同:HashTable初始数组长度为:11个 ,HashMap初始数组长度为16个
3.HashTable线程同步,HashMap线程不同步。
4.HashTable老集合1.0版本就有,HashMap是1.2才加入。
4.HashTable:put的方法是前插,HashMap1.8:put方法是后插。
TreeMap:
底层:基于红黑树的实现。 红黑树是基于排序二叉树。
TreeMap使用:key对象需要实现Comparable接口并重写compareTo方法,内部会给key强转为Comparable对象并掉用compareTo比较对象的大小,如果不实现会抛转换异常。
如果key对象没有实现可以使用Comparator:自定义比较器 。
TreeMap的比较器:
Comparable:自然比较器(比较)
Comparator:自定义比较器
TreeMap集合创建时没有传入比较器此类默认使用自然比较器,如果传入了自定义比较器使用自定义比较器。
TreeMap优点和缺点?
此树是排序的树,实现2分查找(折半查找)查找的的效率高,内存动态分配不存在扩容。删除效率高只需改变引用。
缺点:比较复杂,一般不好驾驭。
LinkedHashMap:底层也是一个HashMap实现不同的多了一个双向链表维护了存储的顺序。在HashMap添加时new节点时会 到LinkedHashMap中创建并将节点添加到双向链表中
LinkedHashMap----HashMap