一、HashMap 与 HashTable 有什么区别?
1.线程安全: HashMap 是非线程安全的,HashTable 是线程安全的; HashTable 内部的方法基本都经过 synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!);
2.效率: 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。另外,HashTable 基本被 淘汰,不要在代码中使用它;
3.对Null key 和Null value的支持: HashMap 中,null 可以作为键,这样的键只有一个,可以有一 个或多个键所对应的值为 null。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛 NullPointerException。
4.初始容量大小和每次扩充容量大小的不同: ①创建时如果不指定容量初始值,Hashtable 默认的 初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后 每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你 给定的大小,而 HashMap 会将其扩充为2的幂次方大小。也就是说 HashMap 总是使用2的幂作为 哈希表的大小,后面会介绍到为什么是2 的幂次方。
5.底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈 值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。
6.推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境 下使用 HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代。
二、如何决定使用 HashMap 还是TreeMap?
对于在Map中插入、删除和定位元素这类操作,HashMap是 好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小, 也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历
三、HashMap 和 ConcurrentHashMap 的区别
1. ConcurrentHashMap对整个桶数组进行了分割分段(Segment),然后在每一个分段上都用lock锁进 行保护,相对于HashTable的synchronized 锁的粒度更精细了一些,并发性能更好,而HashMap 没有锁机制,不是线程安全的。(JDK1.8之后ConcurrentHashMap启了一种全新的方式实现,利用 CAS算法。)
2. HashMap的键值对允许有null,但是ConCurrentHashMap都不允许。
四、ConcurrentHashMap 和 Hashtable 的区别?
ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同。
底层数据结构: JDK1.7的 ConcurrentHashMap 底层采用 分段的数组 +链表 实现,JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑 二叉树。Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 数组+链表 的形式,数组 是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的;
实现线程安全的方式:
① 在JDK1.7的时候,ConcurrentHashMap(分段锁) 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一 部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。(默认分配16 个Segment,比Hashtable效率提高16 倍。) 到了 JDK1.8 的时候已经摒弃了Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。(JDK1.6以后 对 synchronized锁做了很多优化) 整个看起来就像是优 化过且线程安全的 HashMap,虽然在JDK1.8中还 能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本。
② Hashtable(同一把锁) :使用 synchronized 来保证线程安全,效率非常低下。当一个线程访问同步方法 时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使 用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。
两者对比图:
HashTable:
JDK1.7的ConcurrentHashMap:
JDK1.8的ConcurrentHashMap(TreeBi(img)n: 红黑二叉树节点 Node: 链表节点):
ConcurrentHashMap 结合了 Hash(img)Map 和 HashTable 二者的优势。 HashMap 没有考虑同 步,HashTable 考虑了同步的问题。但是 HashTable 在每次同步执行时都要锁住整个结构。 ConcurrentHashMap 锁的方式是稍微细粒度的。
五、Array 和 ArrayList 有何区别?
1、Array 可以存储基本数据类型和对象,ArrayList 只能存储对象。
2、Array 是指定固定大小的,而 ArrayList 大小是自动扩展的。
3、Array 内置方法没有, ArrayList内置方法 多,比如 addAll、removeAll、iteration 等方法只有 ArrayList 有。
对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时 候,这种方式相对比较慢。
六、comparable 和 comparator的区别?
1、comparable接口实际上是出自java.lang包,它有一个 compareTo(Object obj)方法用来排序
2、comparator接口实际上是出自 java.util 包,它有一个compare(Object obj1, Object obj2)方法用 来排序
一般我们需要对一个集合使用自定义排序时,我们就要重写compareTo方法或 compare方法,当我们 需要对某一个集合实现两种排序方式,比如一个song对象中的歌名和歌手名分别采用一种排序方法的 话,我们可以重写compareTo方法和使用自制的Comparator方法或者以两个Comparator来实现歌名 排序和歌星名排序,第二种代表我们只能使用两个参数版的Collections.sort().
七、Collection 和 Collections 有什么区别?
1、java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操 作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为 各种具体的集合提供了 大化的统一操作方式,其直接继承接口有List与Set。
2、Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进 行排序、搜索以及线程安全等各种操作。
八、Vector,ArrayList, LinkedList的区别是什么?
1. Vector、ArrayList都是以类似数组的形式存储在内存中,LinkedList则以链表的形式进行存储。
2. List中的元素有序、允许有重复的元素,Set中的元素无序、不允许有重复元素。
3. Vector线程同步,ArrayList、LinkedList线程不同步。
4. LinkedList适合指定位置插入、删除操作,不适合查找;ArrayList、Vector适合查找,不适合指定 位置的插入、删除操作。
5. ArrayList在元素填满容器时会自动扩充容器大小的50%,而Vector则是100%,因此ArrayList更节 省空间。
九、HashTable, HashMap,TreeMap区别?
1. HashTable线程同步,HashMap非线程同步。
2. HashTable不允许有空值,HashMap允许有空值。
3. HashTable使用Enumeration,HashMap使用Iterator。
4. HashTable中hash数组的默认大小是11,增加方式的old*2+1,HashMap中hash数组的默认大小 是16,增长方式一定是2的指数倍。
5. TreeMap能够把它保存的记录根据键排序,默认是按升序排序。