集合篇
说一下Java中的集合体系
Collection接口
List:表示有序(存入和取出)可重复集合,可以保存null元素
- ArraryList:底层基于数组,查询性能高,增删插性能低
- LinkedList:底层基于双向链表,查询性能低,增删插性能高
- Vector:就是线程安全的ArraryList
Set:表示无序不可重复集合,可以保存null元素
- HashSet:无序不重复的,使用HashMap的key存储元素,判断重复的依据是先判断hashCode值,如果hashCode值相等,再进行equals比较,如果都相等则认为是同一元素
- TreeSet:有序不重复的,底层使用TreeMap的key存储元素,排序方式分为自然排序,比较器排序
Map接口
- HashMap:key的值没有顺序,线程不安全
- TreeMap:key的值可以自然排序,线程不安全
- HashTable:它的key和value都不允许为null,线程安全
- ConcurrentHashMap : 就是一个线程安全且效率更高的的HashMap,理论上是Hashtable的16倍
- LinkedHashMap: 就是一个内部维护了一个双向链表的HashMap,可以保证存入和取出顺序
- Properties:它的key和value都是String类型的,线程安全,常用来做配置文件
HashMap和HashTable的区别
HashMap和HashTable都是实现了Map接口的集合框架,他们的区别
- HashMap是线程不安全的,它实现方法没有加synchronized,因此它的性能较高
- HashTable是线程安全的,它的实现方法都加了synchronized关键字,因此它的性能较低
- HashMap的key和value都允许为null,HashTable中的key和value都不能为null,如果不考虑线程安全,建议使用HashMap,如果需要考虑线程安全的高并发实现,建议使用ConcurrentHashMap
ArrayList和LinkedList区别
都属于线性结构,ArrayList是基于数组实现的,开辟的内存空间要求连续,可以根据索引随机访问元素性能高,但是插入和删除元素性能差,因为这会涉及到移位操作
LinkedList是基于双链表实现的,开配的内存空间不要求连续,因此不支持索引,查找元素需要从头查找,因此性能差,但是添加删除只需要改变指针指向即可,性能高. LinkedList会增加内存碎片化,增加内存管理难度
根据实际需要,如果项目中使用查找较多,使用ArrayList,如果使用增删较多,请使用LinkedList
ArrayList和Vector区别
ArrayList是线程不安全的,Vector相反是线程安全的,方法加了同步锁,线程安全但是性能差,ArrayList底层数组容量不足时,会自动扩容0.5倍,Vector会自动扩容1倍
一个User的List集合,如何实现根据年龄排序
第一种方式:让User类实现Comparable接口,重写compareTo方法,在方法中自定义根据年龄比较的算法
第二种方式:调用Collection.sort方法,传入一个比较器,重写compare方法,方法中自定义根据年龄比较的算法。
HashMap底层用到了那些数据结构?
JDK1.7及其之前:数组,链表 ;
JDK1.8开始:数组,链表,红黑树
HashMap:基于hashCode(),底层是键值对的数组,数组中装装的是键值对,会根据添加的key的hashCode值 模 当前数组的length(默认是16),而得到数组的下标,进而保存键值对。如果key模length后,得到的下标是相等的,就会发生hash碰撞(哈希冲突),这时候再继续判断key的equals方法,如果equals判断为true,就会将原来的键值对覆盖,如果是false,就会在该下标处的原来键值对后面形成 链表,如果链表长度达到8个,就形成红黑树。当删除键值对后剩余的数量小于等于6的时候,就重新将红黑树,退化为链表。(jdk1.8)
key判断键是否重复和HashSet判断重复一样:1. hashCode 2.equals()