Java集合
Java中的集合类主要有:set,list,map。
- Collection: 是集合set,list最基本的接口。
- Iterator:迭代器:可以通过迭代器遍历集合中的元素。
- Map:映射表常用接口。
List
ArrayList
- ArrayList是list集合中常用的list类,其内部是由数组实现的,它擅长对元素的修改和查找,但不适合对元素的增加和删除,因为增加删除一个元素都需要对数组进行复制和移动。
- ArrayList是线程不安全,允许同一时刻多个线程同时访问一个共用的元素。
- 当容量不够时,ArrayList的容量 = 当前容量*1.5 + 1的扩容机制扩容。
Vector(数组实现,线程同步)
- Vector与ArrayList都是通过数组实现,但不同的是Vector实现了线程同步,即同一时刻只能由一个线程访问共有元素,保证了线程安全,但实现线程同步会导致相对于ArrayList对元素修改和删除速度相对较慢。
- 当容量不够时,Vector默认按一倍扩容机制扩容。
LinkedList(链表)
- LinkedList是使用链表存储数据的一种数据结构,它不擅长随机访问数据,但很适合动态添加和删除元素。
- 其底层是一个双向链表,元素可以进行头插法或者尾插法。
- 线程不安全。
HashSet(Hash表)
- HashSet存储元素的顺序不是按存入元素的顺序来存储元素,而是按照哈希值通过一定算法计算出一个索引值来存储元素,当然取元素也是按照这个方法来取元素,而哈希值是通过HashCode()方法来获取的。
- HashSet判断两个元素是否为同一个元素的方法是:先通过判断两个元素的哈希值是否相同,若两个元素的哈希值相同再进一步比较equals()方法,如果equals()方法的是true则视为同一元素如果equals()方法返回的是false则视为不同元素。
- HashSet的底层其实是HashMap。
TreeSet(二叉树)
- TreeSet是使用二叉树的原理对新add中的对象进行排序,每增加一个对象都会进行排序,将对象插入指定二叉树的位置。
- Integer和String对象都可以进行默认的TreeSet排序,而自定义的对象是不可以的,自定义的类必须实现Comparable接口,并重写compareTo()方法,才可以正常使用。
HashMap(数组+链表+红黑树)
- HashMap根据key的哈希值通过一定算法计算出一个合理的索引来存储数据。大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但是遍历顺序确实不确定的。
- HashMap最多只允许一条记录的key为null,允许多条记录的值为null。
- HashMap是线程不安全的,如果同一时刻多个线程同时访问,会导致数据不一致。
- 当HashMap的数组大小大于64以及当某个链表长度大于等于8是时该链表将会转化为红黑树(当然这只是再Java8之后的版本才有的红黑树)。
- HashMap的数组大小是按照两倍扩容机制进行扩容。
因此再Java8中,当数组长度大于等于64且链表长度大于等于8以后会将链表转化为红黑树,在这些位置进行查找的时候可以降低时间复杂度为O(logN)。
ConcurrentHashMap
- ConcurrentHashMap其实和HashMap思路差不多,但支持并发操作。
- 整个ConcurrentHashMap由一个个Segment组成,Segment组成,Segment代表"部分"或"一段"的意思,所以将其描述为分段锁。
3.ConcurrentHashMap是一个Segment数组,Segment通过继承ReentrantLock来进行加锁,所以每次需要加锁锁住的是一个Segment,这样只要保证每个Segments是线程安全的,也就实现了全局线程安全。
ConcurrentHashMap在Java8之后的底层结构和HashMap大同小异。
TreeMap(可排序)
- TreeMap实现SortedMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Interator遍历TreeMap时,得到的记录是排过序的。
- 如果使用排序的映射建议使用TreeMap。
- 在使用TreeMap时,key必须实现Comparable接口或者在构造TreeMap传入自定义的Comparator,否则会在运行时抛出 java.lang.ClassCastException 类型的异常。