Java基础知识面试题系列七:81~90题
- 81.Java Collections框架是什么
- 82.什么是迭代器
- 83.Iterator与ListIterator有什么区别
- 84.ArrayList、Vector和LinkedList有什么区别
- 85.ArrayList、Vector和LinkedList容器使用场景选择
- 86.HashMap、Hashtable、TreeMap和WeakHashMap有哪些区别
- 87.HashMap、TreeMap、LinkedHashMap使用场景的区别
- 88.在Hashtable上下文中,同步指的是什么
- 89.如何实现HashMap的同步?
- 90.Collection和Collections有什么区别
81.Java Collections框架是什么
Java Collections框架中包含了大量集合接口以及这些接口的实现类和操作算法(排序、查找、反转、复制、替换、取最小元素、取最大元素等),主要提供了List(列表)、Queue(队列)、Set(集合)、Stack(栈)和Map(映射表,用于存放健值对)等数据结构。其中,List、Queue、Set、Stack都继承自Collection接口。
Collection是整个集合框架的基础,里面存储一组对象,表示不同类型的Collections,作用是提供一组对象的基本接口。
Set接口:
- 特点是集合中的元素不能重复,存入Set的每一个元素都必须定义equals()方法来确保对象的唯一性。
- 该接口有两个实现类:HashSet和TreeSet。
- 其中TreeSet实现了SortedSet接口,TreeSet容器中的元素是有序的。
List接口:
- List又称为有序的Collection。按对象进入的顺序保存对象,能对列表中的每个元素的插入和删除位置进行精确的控制。
- 可以保存重复的对象。
- LinkedList、ArrayList和Vector都实现了List接口
Map接口:
- Map提供了一个从键映射到值的数据结构。
- 用于保存健值对,值可以重复,但键是唯一的,不能重复
- Java类库中有多个实现该接口的类:HashMap、TreeMap、LinkedHashMap、WeakHashMap和IdentityHashMap.
- 实现了相同的接口,但执行效率却不是完全相同的。
- HashMap是基于散列表实现的,采用对象的HashCode可以进行快速查询。
- LinkedHashMap采用列表来维护内部的顺序。
- TreeMap基于红黑树的数据结构来实现的,内部元素是按需排列的。
82.什么是迭代器
迭代器是一个对象,工作是遍历并选择序列中的对象,提供了一种访问一个容器对象中的各个元素,又不必暴露该对象内部细节的方法。通过迭代器,开发人员不需要了解容器底层的结构,就可以实现对容器的遍历。由于创建迭代器的代价小,因此迭代器通常被称为轻量级的容器。
迭代器的使用主要有以下3个方面的注意事项:
- 使用容器的iterator()方法返回一个Iterator,然后通过Iterator的next()方法返回第一个元素。
- 可以通过remove()方法删除迭代器返回的元素。
Iterator支持派生的兄弟成员。ListIterator只存在于List中,支持在迭代期间向List中添加或删除元素,并且可以在List中双向滚动。
Iterator的使用方法如下所示:
import java.util.*;
public class IteratorTest {
public static void main(String[] args) {
LinkedList<String> ll = new LinkedList<>();
ll.add("first");
ll.add("second");
ll.add("third");
ll.add("fourth");
for(Iterator<String> iter = ll.iterator(); iter.hasNext();){
String str = (String)iter.next();
System.out.println(str);
}
}
}
运行结果如下所示:
first
second
third
fourth
在使用iterator()方法时经常会遇到ConcurrentModificationException异常,通常是由于在使用Iterator遍历容器的同时又对容器做增加或删除操作导致的。
解决方法如下:
- 在遍历的过程中把需要删除的对象保存到一个集合中,等遍历结束后在调用removeAll()方法来删除,或者使用iter.remove()方法。
83.Iterator与ListIterator有什么区别
Iterator只能正向遍历集合,适用于获取移除元素,ListIterator继承自Iterator,专门针对List,可以从两个方向遍历List,同时支持元素的修改。
84.ArrayList、Vector和LinkedList有什么区别
- ArrayList、Vector、LinkedList类均在java.util包中,均为可伸缩数组,可以动态改变长度的数组。
- ArrayList和Vector都是基于存储元素的Object[] array来实现的,会在内存中开辟一块连续的空间来存储,数据存储是连续的。支持用序号来访问元素,同时索引数据的速度比较快。但是在插入元素时需要移动容器中的元素,所以对数据的插入操作执行的比较慢。
ArrayList与Vector的最大区别:
- ArrayList与Vector最大的区别是synchronization(同步)的使用,没有一个ArrayList的方法是同步的,而Vector的绝大多数方法(例如add、insert、remove、set、equals、hashcode等)都是直接或者间接同步的,所以Vector是线程安全的,ArrayList不是线程安全的。正是由于Vector提供了线程安全机制,性能上逊于ArrayList。
LinkedList:
- 采用了双向列表来实现的,对数据的索引需要从列表头开始遍历,因此用于随机访问则效率比较低,但是插入元素时不需要对数据进行移动,因此插入效率较高。同时,LinkedList是非线程安全的容器。
85.ArrayList、Vector和LinkedList容器使用场景选择
- 当对数据的主要操作为索引或只在集合的末端增加、删除元素时,使用ArrayList或Vector效率比较高。
- 当对数据的操作主要为指定位置的插入或删除操作时,使用LinkedList效率比较高。
- 当在多线程中使用容器时(即多个线程会同时访问该容器),选用Vector比较安全。
86.HashMap、Hashtable、TreeMap和WeakHashMap有哪些区别
Java为数据结构的映射定义了一个接口java.util.Map,包括3个实现类:HashMap、Hashtable和TreeMap。
- Map是用来存储健值对的数据结构,在数组中通过数组下标来对其内容索引的。
- Map中则是通过对象来进行索引,用来索引的对象叫做key,对应的对象叫做value。
HashMap:
- HashMap是一个最常用的Map,根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。
HashMap与Hashtable都采用了hash法进行索引,二者有许多相似之处,主要有如下一些区别:
- HashMap是Hashtable的轻量级实现(非线程安全的实现),都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),注意最多只允许一条记录的键为null,不允许多条记录的值为null,而Hashtable不允许。
- HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。Hashtable继承自Dictionary类,HashMap引进Map interface的一个实现。
- Hashtable的方法是线程安全的,HashMap不支持线程的同步,不是线程安全的。在多个线程访问Hashtable时,不需要开发人员对它进行同步,而对于HashMap,开发人员必须提供额外的同步机制。就效率而言,HashMap可能高于Hashtable。
- Hashtable使用Enumeration,HashMap使用Iterator
- Hashtable和HashMap采用的hash/rehash算法几乎一样,性能不会有很大差异
- 在Hashtable中,hash数组默认大小是11,增加的方式是oldx2+1。在HashMap中,hash数组的默认大小是16,而且一定是2的指数。
- hash值的使用不同,Hashtable直接使用对象的hashCode.
WeakHashMap与HashMap的区别:
- WeakHashMap中key采用的是弱引用的方式,只要WeakHashMap中的key不再被外部引用,就可以被垃圾回收器回收。
- HashMap中key采用的是强引用的方式,当HashMap中的key没有被外部引用时,只有在这个key从HashMap中删除后,才可以被垃圾回收器回收。
使用最多的是HashMap,HashMap里面存入的键值对在取出时没有固定的顺序,是随机的。
87.HashMap、TreeMap、LinkedHashMap使用场景的区别
- 在Map中插入、删除和定位元素,HashMap是最好的选择。
- TreeMap实现了SortMap接口,能够把它保存的记录根据键排序,取出来的是排序后的健值对,需要按自然顺序或自定义顺序遍历键,TreeMap会更好。
- LinkedHashMap是HashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,还可以按读取顺序来排列。
88.在Hashtable上下文中,同步指的是什么
同步意味着在一个时间点只能有一个线程可以修改hash表,任何线程在执行Hashtable的更新操作前都需要获取对象锁,其他线程则等待锁的释放。
89.如何实现HashMap的同步?
HashMap可以通过Map m = Collections.synchronizedMap(new HashMap())来达到同步的效果。该方法返回一个同步的Map,该Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多个线程的环境中也是安全的。
90.Collection和Collections有什么区别
Collection是一个集合接口。
- 提供了对集合对象进行基本操作的通用接口方法。
- 实现该接口的类主要有List和Set。
- 该接口的设计目标是为各种具体的集合提供最大化的统一的操作方式。
Collections是针对集合类的一个包装类,它提供一系列静态方法以实现对各种集合的搜索、排序、线程安全化等操作,其中大多数方法都是用来处理线性表。
- Collections类不能实例化,如同一个工具类,服务于Collection框架。
- 若在使用Collections类的方法时,对应的collection的对象为null,则这些方法都会抛出NullPointerException。
import java.util.*;
public class CollectionsTest {
public static void main(String[] args) {
List <Integer> list = new LinkedList<Integer>();
int [] arr = {1,8,4,6};
for(int i = 0; i < arr.length;i++){
list.add(new Integer(arr[i]));
}
Collections.sort(list);
for(int i = 0;i<arr.length;i++){
System.out.println(list.get(i));
}
}
}
如下所示:
1
4
6
8