参考Java程序员面试笔试宝典:
目录
3.ArrayList、Vector、LinkedList有什么区别
4.HashMap、Hashtable、TreeMap、WeakHashMap的区别
5.用自定义类型作为HashMap或Hashtable的key需要注意的问题
6.Collection 和 Collections 有什么区别
1.Java Collections框架是什么
Java Collections 框架包含了大量集合接口以及这些接口的实现类和操作它们的算法(如排序、查找、反转、替换、复制、取最小元素、取最大元素等)。具体而言,主要提供了List(列表)、Queue(队列)、Set(集合)、Stack(栈)和Map(映射表,存放键值对)。其中,List、Queue、Set、Stack都继承自Collection接口。
Collection 是整个集合框架的基础,储存了一组对象,表示不同类型的Collections,它的作用只是维护一组对象的基本接口。
下面简要介绍Set、List、Map3个接口。
1)Set表示数学意义上的集合概念。主要特点是集合中元素不能重复,因此存入Set的每个元素都必须定义equals()方法确保对象的唯一性。该接口有两个实现类 HashSet 和 TreeSet。其中 TreeSet 实现了 SortedSet 接口,TreeSet 容器中元素是有序的。
2)List 又称为有序的 Collection。按对象进入顺序保存对象,能对列表中每个元素的插入和删除位置进行精确的控制。同时可以保存重复对象。LinkedList、ArrayList、Vector都实现了List接口。
3)Map提供了一个从键映射到值的数据结构。它用于保存键值对,其中值可以重复,但键是唯一的。Java类库中有多个实现该接口的类:HashMap、TreeMap、LinkedHashMap、WeakHashMap、IdentityHashMap。
2.什么是迭代器
迭代器(Iterator)是一个对象,工作是遍历并选择序列中的对象,它提供了一种访问一个容器(container)对象中的各个元素,而有不必暴露该对象内部细节的方法。
通过迭代器,开发人员不需要了解容器底层的结构,就可以实现对容器的遍历。
由于创建迭代器地代价较小,通常也称为轻量级地容器。
迭代器使用注意事项:
1)使用容器 iterator() 方法返回一个Iterator,然后通过Iterator的next()方法返回第一个元素
2)使用 Iterator 的 hasNext() 方法判断容器中是否还有其他元素,如果有,可使用 next() 方法获取下一元素。
3)可通过 remove() 方法删除迭代器返回的元素。
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class IteratorTest {
public static void main(String[] args) {
List<String> ll=new LinkedList<>();
ll.add("one");
ll.add("two");
ll.add("three");
ll.add("four");
for(Iterator<String> iter=ll.iterator();iter.hasNext();){
String str = iter.next();
System.out.println(str);
}
}
}
结果:
one
two
three
four
引申:Iterator 与 ListIterator 有什么区别?
Iterator只能正向遍历集合,适用于获取移除元素。ListIterator 继承自 Iterator,专门针对 List,可从两个方向遍历 List,同时支持元素修改。
3.ArrayList、Vector、LinkedList有什么区别
ArrayList、Vector、LinkedList均在java.util包中,均为可伸缩数组,即可动态改变长度的数组。
ArrayList 和Vector 都是基于存储元素的 Object[] array 实现的,在内存中开辟一块连续的空间存储,支持用序号(下标)访问元素,索引数据的速度比较快。在插入时需要移动容器中的元素,执行速度较慢。
ArrayList 和 Vector 都有一个初始化的容量大小,当超过上限就需要动态扩充内存空间。为了提高效率,每次扩充不是简单扩充一个存储单元。Vector默认扩充为原来2倍(可设置),而 ArrayList 默认原来的1.5倍(没有提供方法设置空间扩充)。
ArrayList 和 Vector 的最大区别就是 synchronization(同步)的使用,没有一个 ArrayList 的方法是同步的,而 Vector 绝大多数方法(如add、insert、remove、set、equals、hashcode等)都是直接或间接同步。所以 Vector 是线程安全的,ArrayList 不是线程安全的。正是因为 Vector 提供线程安全机制,性能上略逊于ArrayList。
LinkedList 采用双向列表实现,对数据的索引需要从列表头开始遍历,因此随机访问效率比较低,但插入元素不需要移动数据,插入效率比较高。LinkedList 是非线程安全容器。
如何选择容器?
对数据主要操作为索引或只在集合末端增删元素时,使用 ArrayList 或 Vector 效率比价高;
对数据操作主要为指定位置插入或删除操作,使用 LinkedList 效率比较高;
在多线程中使用容器(即多个线程同时访问该容器),选用 Vector 较为安全。
4.HashMap、Hashtable、TreeMap、WeakHashMap的区别
Java为数据结构的映射定义了一个接口 java.util.Map,它包括三个实现类:HashMap、Hashtable、TreeMap。Map用来存储键值对,在数组中通过数组下标对其内容索引,在 Map 中,通过对象进行索引,用来索引的对象叫key,其对于对象叫value。
HashMap 是一个最常用的 Map,根据键的 HashCode 值存储数据,根据键直接获取值,具有很快的访问速度。HashMap 与 Hashtable都采用 hash 法索引,有许多相似之处,现列出一些区别:
1)HashMap是Hashtable的轻量级实现(非线程安全实现),都完成了Map接口,区别在于 HashMap 允许空(null)键值(key),但最多只允许一条记录的键为 null,不允许多条;而 Hashtable 不允许。
2)HashMap 把 Hashtable 的 contains 方法去掉了,改成containsvalue 和 containskey,因为contains方法容易让人误解。Hashtable继承自Dictionary 类,而HashMap 是Java 1.2 引进的 Map interface 的一个实现。
3)Hashtable是线程安全的,而HashMap不支持线程同步,不是线程安全,当多线程访问时,需要开发人员提供额外同步机制。因此就效率而言,HashMap 可能高于 Hashtable。
4)Hashtable 使用 Enumeration,HashMap使用 Iterator。
5)HashMap 和 Hashtable采用的 hash/rehash 算法几乎一样,所以性能不会有很大的差异。
6)Hashtable中,hash默认数组大小为11,增加方式为old*2+1;在 HashMap 中,hash默认数组大小为16,且一定是2的指数。
7)hash值的使用不同,Hashtable直接使用对象的hashCode。
以上三种类型HashMap使用最多,存入的键值对取出时顺序随机。一般而言,在Map中插入、删除、定位元素,HashMap是最好的选择。
TreeMap实现了SortMap接口,能将保存的记录根据键排序,因此,取出是排序后的键值对,若需要按自然顺序或自定义顺序遍历键,TreeMap会更好。
LinkedHashMap是HashMap的一个子类,若需要输出顺序和输入相同,则使用LinkedHashMap,它可按读取顺序排列。
WeakHashMap与HashMap类似,不同之处在于WeakHashMap中的key采用“弱引用”,只要WeakHashMap中的key不再被外部引用,就可被垃圾回收器回收;而HashMap中的key采用“强引用”方式,当HashMap中的key没被外部引用,只有这个key从HashMap中删除,才能被垃圾回收器回收。
笔试题:
1.在Hashtable上下文中,同步指的是什么?
同步意味着一个时间点只能有一个线程可以修改hash表,任何线程在执行Hashtable的更新操作前需要获取对象锁,其他线程需等待锁的释放。
2.如何实现HashMap的同步?
HashMap通过 Map m = Collections.synchronizedMap(new HashMap()) 来达到同步效果。具体而言,该方法返回一个同步Map,该Map封装了底层的HashMap所有方法,使得底层的HashMap即使在多线程环境也是安全的。
5.用自定义类型作为HashMap或Hashtable的key需要注意的问题
1)如果想根据对象的相关属性来自定义对象是否相等的逻辑,此时需要重写equals()方法,一旦重写equals()方法,就要重写hashCode()方法。
2)当自定义类的多项作为HashMap或Hashtable的key时,最好把这个类设计为不可变类。
3)从HashMap工作原理看,如果两个对象相等,那么两个对象有着相同的hashCode,反之不成立。
6.Collection 和 Collections 有什么区别
Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。实现该接口的类主要有List和Set,该接口的设计目标是为各种具体的集合提供最大化的统一操作方式。
Collections 是针对集合类的一个包装类,它提供了一系列静态方法以实现对各种集合的搜索、排序、线程安全化等操作,其中大多数方法用来处理线性表。
Collections 不能实例化,如同一个工具类,服务于 Collection 框架。若在使用 Collections 类的方法时,对应的 Collection 的对象为null,会抛出 NullPointerException。
使用Collections示例:
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class Test{
public static void main(String[] args) {
List<Integer> list = new LinkedList<>();
int array[] = {7,3,5,1};
for (int i = 0; i < array.length; i++) {
list.add(new Integer(array[i]));
}
Collections.sort(list);
for (int i = 0; i < array.length; i++) {
System.out.println(list.get(i));
}
}
}
结果:
1
3
5
7