对比Hashtable、HashMap、TreeMap有什么不同?
写这里的时候我是很迷茫的,下面这张图就是我对集合这部分了解的全部了。老师在集合这部分涉及到了许多算法的知识,我算法的程度仅到了解几个简单的排序算法。几乎每章都会对线程安全问题进行分析,线程我就记了一个锁机制。还有 jdk 源码的一些分析,我根本看不下去。JVM 的内容,我也没学过。导致我看集合这部分的文章几乎什么都没学到,我尽量整理一些我能理解的内容。理解不了的就暂时放着了。大家想了解这部分的内容的话,先去看其他人写的吧。
容器
三者的区别
-
Hashtable:线程安全,效率有所降低,不支持
null
键和值,底层数据结构是数组+链表,由于同步导致的性能开销,所以已经很少被推荐使用。 -
HashMap:线程不安全,支持
null
键值,底层数据结构为数组+链表/红黑树,链表长度大于8(默认长度)时,自动转换为红黑树。它是绝大部分利用键值对存取场景的首选 - TreeMap 是基于红黑树的一种提供顺序访问的 Map,和 HashMap 不同,它的 get、put、remove 之类操作都是 O(log(n))的时间复杂度,具体顺序可以由指定的 Comparator 来决定,或者根据键的自然顺序来判断。
HashMap 源码分析
补充
hashCode ()与equals ()的相关规定:
- 如果两个对象相等,则hashcode- -定 也是相同的
- 两个对象相等,对两个equals方法返回true
- 两个对象有相同的hashcode值,它们也不一定是相等的
- 综上,equals方法被覆盖过,则hashCode方法也必须被覆盖
- hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),
则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。
如何选用集合?
主要根据集合的特点来选用,比如我们需要根据键值获取到元素值时就选用Map
接口下的集合,需要排序时选择TreeMap,
不需要排序时就选择HashMap,
需要保证线程安全就选用ConcurrentHashMap.
当我们只需要存放元素值时,就选择实现Collection
接口的集 合,需要保证元素唯一时选择实现Set
接口的集合比如TreeSet
或HashSet,
不需要就选择实现List
接口的比如ArrayList
或LinkedList
,然后再根据实现这些接口的集合的特点来选用。
Comparable和Comparator的区别
-
comparable
接口实际 上是出自java.lang
包它有一个compareTo(0bject obj)
方法用来排序 -
comparator
接口实际上是出自java.util
包它有一个compare(0bject obj1, object obj2)
方法用来排序。一般我们需要对一个集合使用自定义排序时,我们就要重写compareTo()
方法或compare()
方法,当我们需要对某一一个集合实现两种排序方式,比如一个song
对象中的歌名和歌手名分别采用一种排序方法的话,我们可以重写compareTo()
方法和使用自制的Comparator
方法或者以两个Comparator
来实现歌名排序和歌星名排序,第二种代表我们只能使用两个参数版的Collections.sort().
- 包装类已经实现了 Comparable