List的实现类
ArrayList
底层使用数组存储数据,插入和删除的效率低,检索的效率高。
会自行进行扩容,每次扩容1.5倍
使用无参构造器时,会在第一次使用add时创建长度为10的数组
非线程同步,安全性低,但效率低
Vector
底层也是用数组存储
线程同步,安全性高,但效率低
自行扩容时扩容2倍,也可自定义扩容
LinkedList
底层使用双向链表存储数据,插入删除效率高,检索效率低
Set的实现类
HashSet
底层使用HashMap存储数据,相当如只存入了Map中的key,没存入value;
使用一个固定的值作为value的值,防止value为null导致保存失败,也防止过多的value值浪费空间
TreeSet
底层使用TreeMap存储数据,存入的key是自然有序的。
TreeSet中存入的元素,需要可以进行自身比较大小或是存在第三方比较器
使用第三方比较器是构造方法如下
public TreeSet(Comparator comparator){}
Map的实现类
HashMap
底层使用数组+链表的形式存储数据,jdk1.8后还会使用红黑树存储数据
每次存入的元素(key),根据元素的hashcode值,再通过hash算法的计算,计算出数组存储的位置,存储位置是零散的,第一个数据不一定在存储在第一个位置。
元素的hashcode值是通过调用hashcode方法获得的,该方法在Object中,使用native修饰,是使用jvm(c/c++)实现的。
对象在第一次调用hashcode方法时才会产生hashcode值,hashcode值的作用是为hash存储结构计算存储位置的。
hash的存储特点是元素的快存和快取
为了防止链表过长导致hash效率降低,当链表长度超过8时,会转换成红黑树。
hash碰撞
当两个元素的hashcode值通过hash计算获得一个相同的地址是,会发生hash碰撞。
发生hash碰撞后,新节点会和链表中的每一个节点进行比较,有相等的(hash相等,key相等,equals相等),key去重,value覆盖;没有相等的,将该节点插入链表最后。
HashMap的数组容量使用时2 的次幂,即使制定了初始容量,也会通过处理转换成2的次幂。
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
非线程同步,安全性低,效率高
key和value可以为null
Hashtable
作用和HashMap基本相同
线程同步,安全性高,效率低
key和value不能为空
TreeMap
底层使用红黑树存储数据,BST树的一种。
BST树是一个二叉树,每一个节点有左右两个子节点和一个父节点。左节点<父节点<右节点。
存储:第一个节点为根节点,之后的节点会从根节点开始进行相等比较和大小比较,若相等,则key去重,value覆盖;不相等的话进行大小比较,小与根节点则与左节点再进行比较,大于则与右节点再进行比较,直到左节点或右节点为null时存入。
遍历:
前序遍历:父左右
中序遍历:左父右
后序遍历:左右父
原码,反码,补码
计算机中用补码表示数字
原码
10进制转换成的2进制数,最高位为0表示正数,最高位为1表示负数
反码
正数的反码与原码相同
负数的反码最高位不变,其余位按位取反
补码
正数的补码与原码相同
负数的补码为反码+1
位运算符
对二进制进行计算
&(按位与)
对应位置同时为1,结果为1,有一侧为0,结果为0;
|(按位或)
对应位置同时为0,结果为0,有一侧为1,结果为1
^(按位异或)
对应位置相同为0,不同为1
~(按位取反)
对二进制数按位取反,结果是其相反数-1
计算机中使用补码表示数字,计算~十进制数时,先将十进制数转换成二进制数补码,在按位取反。
<<(左移)
二进制向左移动指定位数,每移动一位相当于*2
>>(无符号右移)
不带符号向右移动,每移动1位,相当于/2
正数右移时补0,负数右移时补1
>>>(带符号右移)