接着上篇继续更新。html
/*请尊重做者劳动成果,转载请标明原文连接:*/java
/* http://www.javashuo.com/article/p-mejzzbml-ga.html* /编程
题目一:Hashtable,HashMap,TreeMap有什么区别?数组
通常回答:
Hashtable 是早期 Java 类库提供的一个哈希表实现,自己是同步的,不支持 null 键和值,因为同步致使的性能开销,因此已经不多被推荐使用。
HashMap 是应用更加普遍的哈希表实现,行为上大体上与 HashTable 一致,主要区别在于 HashMap 不是同步的,支持 null 键和值等。一般状况下,HashMap 进行 put 或者 get 操做,能够达到常数时间的性能,因此它是绝大部分利用键值对存取场景的首选,好比,实现一个用户 ID 和用户信息对应的运行时存储结构。
TreeMap 则是基于红黑树的一种提供顺序访问的 Map,和 HashMap 不一样,它的 get、put、remove 之类操做都是 O(log(n))的时间复杂度,具体顺序能够由指定的 Comparator 来决定,或者根据键的天然顺序来判断。
扩展一下,看看JAVA集合的全集。
上述类图中,实线边框的是实现类,好比ArrayList,LinkedList,HashMap等,折线边框的是抽象类,好比AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,好比Collection,Iterator,List等。
发现一个特色,上述全部的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法。它的一个子接口LinkedIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。也就是说若是是先Iterator接口,那么在遍历集合中元素的时候,只能日后遍历,被遍历后的元素不会在遍历到,一般无序集合实现的都是这个接口,好比HashSet,HashMap;而那些元素有序的集合,实现的通常都是LinkedIterator接口,实现这个接口的集合能够双向遍历,既能够经过next()访问下一个元素,又能够经过previous()访问前一个元素,好比ArrayList。
还有一个特色就是抽象类的使用。若是要本身实现一个集合类,去实现那些抽象的接口会很是麻烦,工做量很大。这个时候就可使用抽象类,这些抽象类中给咱们提供了许多现成的实现,咱们只须要根据本身的需求重写一些方法或者添加一些方法就能够实现本身须要的集合类,工做流昂大大下降。
题目二:Vector,ArrayList,LinkedList有什么区别?缓存
通常回答:
Vector 是 Java 早期提供的线程安全的动态数组,若是不须要线程安全,并不建议选择,毕竟同步是有额外开销的。Vector 内部是使用对象数组来保存数据,能够根据须要自动的增长容量,当数组已满时,会建立新的数组,并拷贝原有数组数据。
ArrayList 是应用更加普遍的动态数组实现,它自己不是线程安全的,因此性能要好不少。与 Vector 近似,ArrayList 也是能够根据须要调整容量,不过二者的调整逻辑有所区别,Vector 在扩容时会提升 1 倍,而 ArrayList 则是增长 50%。
LinkedList 顾名思义是 Java 提供的双向链表,因此它不须要像上面两种那样调整容量,它也不是线程安全的。
继续扩展一下,仍是先看上题中的集合框架图。
咱们能够看到 Java 的集合框架,Collection 接口是全部集合的根,而后扩展开提供了三大类集合,分别是:
List,也就是咱们前面介绍最多的有序集合,它提供了方便的访问、插入、删除等操做。
Set,Set 是不容许重复元素的,这是和 List 最明显的区别,也就是不存在两个对象 equals 返回 true。咱们在平常开发中有不少须要保证元素惟一性的场合。
Queue/Deque,则是 Java 提供的标准队列结构的实现,除了集合的基本功能,它还支持相似先入先出(FIFO, First-in-First-Out)或者后入先出(LIFO,Last-In-First-Out)等特定行为。这里不包括 BlockingQueue,由于一般是并发编程场合,因此被放置在并发包里。
每种集合的通用逻辑,都被抽象到相应的抽象类之中,好比 AbstractList 就集中了各类 List 操做的通用部分。这些集合不是彻底孤立的,好比,LinkedList 自己,既是 List,也是 Deque 哦。
若是阅读过更多源码,你会发现,其实,TreeSet 代码里实际默认是利用 TreeMap 实现的,Java 类库建立了一个 Dummy 对象“PRESENT”做为 value,而后全部插入的元素实际上是以键的形式放入了 TreeMap 里面;同理,HashSet 其实也是以 HashMap 为基础实现的,原来他们只是 Map 类的马甲!
题目三:int和Integer有什么区别?安全
通常回答:
int 是咱们常说的整形数字,是 Java 的 8 个原始数据类型(Primitive Types,boolean、byte 、short、char、int、float、double、long)之一。 Java 语言虽然号称一切都是对象,但原始数据类型是例外。
Integer 是 int 对应的包装类,它有一个 int 类型的字段存储数据,而且提供了基本操做,好比数学运算、int 和字符串之间转换等。在 Java 5 中,引入了自动装箱和自动拆箱功能(boxing/unboxing),Java 能够根据上下文,自动进行转换,极大地简化了相关编程。
扩展:
这里很容易就想到装箱和拆箱。 装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。
这个过程是自动执行的,那么咱们须要看看它的执行过程:
public class Main {
public static void main(String[] args) {
//自动装箱
Integer total = 99;
//自定拆箱
int totalprim = total;
}
}
反编译class文件以后获得以下内容:并发
执行上面那句代码的时候,系统为咱们执行了:
Integer total = Integer.valueOf(99);
int totalprim = total;
执行上面那句代码的时候,系统为咱们执行了:
int totalprim = total.intValue();
那么何时会进行封箱拆箱呢?
当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。
须要注意的是:
1. 装箱操做会建立对象,频繁的装箱操做会消耗许多内存,影响性能,因此能够避免装箱的时候应该尽可能避免。
2.自动拆箱实际是jvm 调用了 intValue 方法,因此性能上不会有影响。
3.除double 和float 两种类型之外,其余基本类型入Integer值 在 -128 ~ 127之间时不会新建一个Integer 对象而是从缓存中获取。因此在作 == 判断时 要注意值得大小,若是超过范围,则两个值 虽然同样但 == 比较的结果会是FALSE。
4.Integer 类型的比较最好用 compare 。
5.比较二者(int 与 Integer变量) 时,能够用拆箱 (用intValue方法),没影响的。