JAVA集合框架面试题(三)

来源:互联网 发布:淘宝字画 编辑:程序博客网 时间:2024/06/05 00:57

1. Java 集合框架的基本接口有哪些?

Collection是总的一个接口,提供了很多多态的方法,供实现它的各种子接口使用。

Set一般来说是无序的collection子接口(这里说的无序是指,不是按照你添加元素的顺序,而是随机生成了一个顺序),不允许有重复的元素(代码上可以编译通过,但实际不会存储两个相同的元素),可以放null元素。但其实现接口SortedSet是一个有序的接口。TreeSet类是具体的实现类。

List是一个有序的集合,可以包含重复的元素,可以包含NULL,提供了按索引访问的方式。

Map 是一个键-值的对象,不能包含重复的key。


2. 为何Collection接口没有实现 Cloneable 和 Serializable 接口?

因为Collection是所有具体实现类或者接口的总上游接口,很多具体实现的集合类都有自己的Clone方法,有些集合类需要支持Clone()方法和序列化,但有些不需要实现,因此这个应该有具体的实现集合类来决定。


3. Enumeration 和 Iterator 接口有什么区别?

1. enumeration 比 iterator 的速度快一倍,占用非常少的内存。

2. Enumeration 是很基础的,只满足基本需要。而Iterator跟Enumeration比起来更安全,因为线程在用Iterator遍历的时候,是拒绝修改元素的。

3. Iterator允许使用者移除元素,Enumeration不可以。


4. Iterator 和ListIterator 有什么区别?

1. Iterator 可以用做遍历Set和List集合,而ListIterator只能遍历List。

2. Iterator只能向前遍历,但ListIterator是双向的,既可以向前,也可以向后遍历。

3. ListIterator 是继承自Iterator,因此增加了一些方法,比如增加元素,替换元素,获取前一个或者后一个的元素的索引。


5. 遍历一个List有哪些方法?

List<String> strList = new ArrayList<>();//using for-each loopfor(String obj : strList){    System.out.println(obj);}//using iteratorIterator<String> it = strList.iterator();while(it.hasNext()){    String obj = it.next();    System.out.println(obj);}

使用Iterator迭代器遍历的方式更安全,因为是线程安全的,遍历的时候如果元素被修改,会报ConcurrentModificationException的错。


6. fail-fast 和 fail-safe 的区别?

1. fail-fast是指在 Iterator 遍历的时候,不允许线程修改collection的元素,否则会抛出ConcurrentModificationException的异常。而fail-safe的则不会受到影响。

2. fail-fast的集合类一般都在java.util包内,而fail-safe的集合类都在java.util.concurrent内。


7. UnsupportedOperationException 是什么错误?

String[] array = new String[2];List list2 = Arrays.asList(array);list2.add("test");//抛出异常
在使用asList的时候,修改集合List就会报错。

8. 可以用我们自己定义的类做HashMap的key么?

可以,但要注意两点,1:要重写equals()和hashcode()方法 ; 2: 这个类要求是不能修改的,否则会导致hashcode不固定。

例:

//MyKey name argument passed is used for equals() and hashCode()MyKey key = new MyKey("Pankaj"); //assume hashCode=1234myHashMap.put(key, "Value"); // Below code will change the key hashCode() and equals()// but it's location is not changed.key.setName("Amit"); //assume new hashCode=7890 //below will return null, because HashMap will try to look for key//in the same index as it was stored but since key is mutated,//there will be no match and it will return null.myHashMap.get(new MyKey("Pankaj")); 

9. HashMap 和 HashTable有何区别?

1. HashMap不是线程安全的,而HashTable是线程安全的;

2 .HashMap是一个map接口的子类,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap允许null key和null value,而HashTable不允许。

10. 什么时候适合使用HashMap,什么时候适合使用TreeMap?

在添加,删除,定位Map的元素的操作上,HashMap比TreeMap更效率。然而当你要按顺序遍历key,则TreeMap是更好的选择。根据集合的大小,使用HashMap添加元素,要按顺序遍历key的时候再转换成TreeMap。


11. ArrayList 和 Vector 有啥区别和相似点?

相似点:

1. 内部都是有索引,而且是有数组构成的。

2. 都是按照插入的顺序存储元素,取出元素的顺序就是插入时候的顺序。

3. 两者的Iterator实现都是设计成fail-fast 的。

4.两者都可以按数组下标快速访问,二者都可以存放null元素。

不同点:

1. Vector是同步的,ArrayList不是同步的。当你在用Iterator遍历过程中应当使用CopyOnWriteArrayList。

2. ArrayList比Vector更快更效率,因为不用考虑线程同步问题。

3. ArrayList更加通用化,因为我们可以通过Collections的通用类来得到线程同步的list和只读的list。


12. Array和ArrayList有什么区别,什么情况用Array而不是ArrayList?

1. Array可以存放基础数据类型也可以存放Object,但ArrayList只能存放Object。

2. Array是固定长度的,而ArrayList是动态长度的。

3. Array提供了很少的特征,而ArrayList提供了很多的方法。

在以下情况应当使用Array:

当List长度固定,且用来存储和遍历用。


13. ArrayList 和 LinkedList 区别?

1. ArrayList是支持快速访问的,找到其中某个元素的时间复杂度为O(1),而LinkedList是使用节点来存储元素,每个节点有个指向前节点的指针和指向后一个节点的指针。时间复杂度为O(n)

2. 添加,移除元素操作使用LinkedList更快,因为ArrayList没有在中间添加元素后,修改List容量或者更新索引的方法。

3.LinkedList需要更多的内存空间,因为它要存放前节点和后节点的指针。


14. 哪些集合类提供了随机访问功能?

ArrayList, HashMap, TreeMap, Hashtable


15. EnumSet是什么?

EnumSet只能存放Enum类型下的元素,EnumSet不能存放NULL,EnumSet不是同步的。一般用EnumSet.noneOf(Enum类型.class),它的元素也是有序的,以枚举值在枚举类的定义顺序来决定集合元素的顺序。

例:

public class EnumSetTest {public static void main(String[] args) {  System.out.println("EnumSet.noneOf");  EnumSet<Student> set=EnumSet.noneOf(Student.class);  set.add(Student.HARRY);  set.add(Student.ROBBIE);  set.add(Student.ROBIN);  set.add(null);  for(Student p:set)   System.out.println(p);  set.clear();  System.out.println("EnumSet.allOf");  set=EnumSet.allOf(Student.class);  for(Student p:set)   System.out.println(p);  set.clear();  System.out.println("EnumSet.Of one");  set=EnumSet.of(Student.ROBIN);  for(Student p:set)   System.out.println(p);  System.out.println("EnumSet.Of two");  set=EnumSet.of(Student.ROBIN,Student.HARRY);  for(Student p:set)   System.out.println(p); }}enum   Student{ ROBIN("robin"), HARRY("harry",40), ROBBIE("robbie"), JAMES("james"), MESSI("Messi"); String name; int age; private Student(String name) {  this(name,0); } private Student(String name,int age) {  this.name=name;  this.age=age; } public String toString() {  return name; }}

16. 哪些集合类是线程安全的?

Vector, Hashtable, Properties 和 Stack 是线程同步的,在JDK1.5之后,有些集合类是允许在Iterator遍历时对元素进行修改的。


17. BlockingQueue是什么?

见博客中另外一篇文章。http://blog.csdn.net/sparic/article/details/37657511


18.Queue和Stack有什么区别?

1.Queue是接口,它的实现类都在concurrent的包下,而Stack是一个类,是实现了Vector接口的类。

2.Queue是按照先进先出(FIFO)的顺序去检索元素,不过也不是都是这样,有个Deque的接口(实现了Queue接口)可以支持从两端检索元素。而Stack类是后进先出(LIFO)的顺序检索元素。


19. Comparable 和Comparator 接口?

待续...


20.如何去排序一个对象的集合?

如果这个集合是对象的数组,则使用Arrays.sort()比较好, 如果是list则使用Collections.sort()比较好,后者的内部实现其实也是用的Arrays.sort(),只是后者比前者多需要一些时间将List转换成Array。


21. 当一个集合作为参数传给某个方法时,怎么确保这个方法不会修改该集合?

可以使用Collections.unmodifiableCollection(Collection c)来创建一个只读的集合,然后再传到方法中,这样任何修改集合的操作都会报UnsupportedOperationException的错。


22. 如何由给定的collection创建一个线程安全的collection?

使用Collections.synchronizedCollection(Collection c) 


23. PriorityQueue 的定义及其使用?

参见另一篇文章 : http://blog.csdn.net/sparic/article/details/37694897



0 0
原创粉丝点击