1.List
list是一个接口下面有两个常用的实现类。
增调用的是add()方法。
删调用的是remove()方法。
1.ArrayList 基于数组实现的
基于数组实现的,查询快(数组有索引),增删慢(牵扯到扩容,拷贝老的数组到新的数组中,每次扩容为原来的1.5倍,),
ArrayList的初始化方法有两种
1.当真正对数组进行添加的时候分配内存,初始值为10。
2.直接为数组的容量定下内存大小。
2.LinkedList 基于链表实现的
基于链表实现的,查询慢(查询的时候需要对链表进行遍历),增删快(因为链表有指针,增删的时候只要修改指着的位置)
2.map
map接口有一个常用的实现类HashMap.
1.HashMap采用的是数组+链表的数据结构。
在查询和修改方面继承了数组的线性查询,和链表的寻址修改。
同样HashMap他也是不安全的,hashMap采用的是数组+链表,当发生hash碰撞的时候,会采用拉链发,在数组的位置形成链表或红黑树,
设想有多个线程同时操作该集合,如果有两个计算出的hash值相同,那么在多线程的情况下肯定会有一只只丢失,这样就是不安全的。
2.HashTable
因为hashMap是不安全的所有就有了线程安全的hashtable,他是通过加锁,通过Synchronized关键字加锁获取线程安全的
3.ConcurrentHashMap
因为hashMap的效率高,但是线程是不安全的,而hashTable虽然线程安全,但是因为加锁的原因,效率低所以,就又了
concurrentHashMap,他在读的时候,几乎是不加锁的,但是在写的时候,只对操作段加锁,这样就能保住很高的效率。
1.HashMap的存储原理
hashMap的存储机制,如果链表得长度超过了8,那么就会将链表装换为红黑树,如果链表的长度低于6,就会将红黑树转化为链表
在java1.7中如果发生了hash碰撞,会在链表的头部插入,而java1.8会在链表的尾部插入。
2.put过程
a.put过程是对key就hash值,然后在计算出下标
b.如果没有发生hash碰撞就直接放到桶中
c.如果发生了hash碰撞,就以链表的形式存连接到链表的后面,
d.如果链表的长度超过了8,就把链表转化为数组,如果链表的长度低于6,就把红黑树转化为链表
e.如果节点已经存在,就替换原来的节点
f.如果桶满(12)了就进行扩容(2b)
3.get过程
a.get过程是对key求hash值,然后计算出下标
b.在通过keys.equals()方法找到链表中正确的值。
3.set
set集合继承Collection。特征是无序、不可重复。
set集合的不可重复:
Set集合每次添加元素的时候,会自动提取两个对象。
然后让两个对象调用自己的hashCode()方法(继承自Object)得到彼此的哈希值(所谓的内存地址)
然后判断两个对象的哈希值是否一样,如果不一样认为两个对象不重复,都保留。
如果两个对象的哈希值一样,Set集合会继续让两个对象进行equlas比较,
如果equlas比较结果不一样,则认为两个对象不重复,都保留。
如果equlas比较结果一样,则认为两个对象重复,保留一个。
HashSet集合的元素为什么是无序的,是如何实现元素无序的。
因为set集合底层是基于哈希表存储的。
jdk1.8之前,哈希表是由:数组和链表组成的,
jdk1.8之后,哈希表是由:数组+链表+排序二叉树组成
二叉树:只有一个zu节点,两个分节点。
排序二叉树:小在左,大在右。