Java集合面试题

ArrayList和Vector的区别

答:这两个类都实现了List接口(List接口继承了Collection接口),它们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与hashset没有任何关系,但为了说清楚ArrayList与Vector的功能,我们使用对比方式,更有利于说明问题)。

接着才说ArrayList与Vector的区别,这主要包括两个方面:. 

(1)同步性:
    Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。
备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。所以,我们讲课时先讲老的。
(2)数据增长:
    ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。
总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。

ArrayList和LinkedList有什么异同之处?

  ArrayList。它实现了可变长度的数组,和数组采用相同的存储方式,在内部分配了连续的空间。有点在于遍历元素和随机访问元素的效率比较高。
  LinkedList采用链表存储方式,它提供了addFirst(),addLast(),removeFirst(),removeLast(),可以在LinkedList的首部或尾部插入或删除元素。优点在与插入,删除元素的效率比较高。

HashMap和Hashtable的区别

   (条理上还需要整理,也是先说相同点,再说不同点)
    HashMap是Hashtable的轻量级实现(非线程安全的实现),它们都实现了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。 
    HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。 
    HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey。因为contains方法容易让人引起误解。 
    Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。 
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问 Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。 
    Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

就HashMap与HashTable主要从三方面来说。 
    1.历史原因:Hashtable是陈旧的Dictionary类的子类的实现了map接口,HashMap是Java 1.2引进的Map接口的一个实现 
    2.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的 
    3.值:只有HashMap可以将空值作为一个表的条目的key或value,而hashtable不可以 

List 和 Map 区别?

List是存储单列数据的集合,Map是存储键和值这样的双列数据的集合,
List中存储的数据是有顺序,并且允许重复;
Map中存储的数据是没有顺序的,键不能重复,值是可以有重复的。

List, Set, Map是否继承自Collection接口?

List,Set是,Map不是

List、Map、Set三个接口,存取元素时,各有什么特点?

这样的题属于随意发挥题:这样的题比较考水平,两个方面的水平:一是要真正明白这些内容,二是要有较强的总结和表述能力。如果你明白,但表述不清楚,在别人那里则等同于不明白。
首先,List与Set具有相似性,它们都是单列元素的集合,所以,它们有一个功共同的父接口,叫Collection。Set里面不允许有重复的元素,所谓重复,即不能有两个相等(注意,不是仅仅是相同)的对象 ,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。Set取元素时,没法说取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。
List表示有先后顺序的集合, 注意,不是那种按年龄、按大小、按价格之类的排序。当我们多次调用add(Obj e)方法时,每次加入的对象就像火车站买票有排队顺序一样,按先来后到的顺序排序。有时候,也可以插队,即调用add(int index,Obj e)方法,就可以指定当前对象在集合中的存放位置。一个对象可以被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并不是把这个对象本身存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个索引指向了这个对象,如图x所示。List除了可以以Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以调用get(index i)来明确说明取第几个。
Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key 所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。

List 以特定次序来持有元素,可有重复元素。Set 无法拥有重复元素,内部排序。Map 保存key-value值,value可多值。

HashSet按照hashcode值的某种运算方式进行存储,而不是直接按hashCode值的大小进行存储。例如,"abc" ---> 78,"def" ---> 62,"xyz" ---> 65在hashSet中的存储顺序不是62,65,78。LinkedHashSet按插入的顺序存储,那被存储对象的hashcode方法还有什么作用呢?HashSet集合比较两个对象是否相等,首先看hashcode方法是否相等,然后看equals方法是否相等。new 两个Student插入到HashSet中,看HashSet的size,实现hashcode和equals方法后再看size。

同一个对象可以在Vector中加入多次。往集合里面加元素,相当于集合里用一根绳子连接到了目标对象。往HashSet中却加不了多次的(不支持重复元素)。 

说出ArrayList,Vector, LinkedList的存储性能和特性

ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据效率较低,Vector由于使用了synchronized(同步)方法(线程安全),通常性能上较ArrayList差。
LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList可以被当作堆栈和队列来使用。

如何去掉一个Vector集合中重复的元素,有几种方法

Vector newVector = new Vector();
for (int i=0;i<vector.size();i++){
 Object obj = vector.get(i);
    if(!newVector.contains(obj);
        newVector.add(obj);
}
还有一种简单的方式,HashSet set = new HashSet(vector); 因为Set集合中不允许出现重复元素,会自动去除掉重复对象。

Collection 和 Collections的区别。

Collection是集合类的顶级接口,继承它的接口主要有Set 和List. 
Collections是针对集合框架的一个算法工具类,它提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

Set里的元素是不能重复的,在Set集合内部实现元素重复与否的判断是使用equals()方法进行比较的。 
两个比较方式的区别是:
1)equals()比较的是对象的值
2)==比较的是对象的内存地址是否相同

你所知道的集合类都有哪些?主要方法?

最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按顺序索引访问元素的情形,Map 提供了一个更通用的元素存储方法。Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。具体的集合实现类如下:
ArrayList/Vector List Collection
HashSet/TreeSet Set
Propeties HashTable Map
Treemap/HashMap Map
我记的不是方法名,而是思想,我知道它们都有增删改查的方法,但这些方法的具体名称,我记得不是很清楚,对于Set,大概的方法是add,remove, contains;对于Map,大概的方法就是put、remove、containsKey、containsValue等,因为,我只要在开发工具(如Eclipse)中按点操作符,很自然的这些方法就出来了。我记住的一些思想就是List类会有get(int index)这样的方法,因为它可以按顺序取元素,而Set类中没有get(int index)这样的方法。List和Set都可以迭代出所有元素,迭代时先要得到一个iterator对象,所以,Set和List类都有一个iterator方法,用于返回那个iterator对象。Map可以返回三个集合,一个是返回所有的key的集合,另外一个返回的是所有value的集合,再一个返回的key和value组合成的EntrySet对象的集合,map也有get方法,参数是key,返回值是key对应的value。 

列出你知道的容器类(就是指集合类),简单说明其功能

Java容器类Collection、List、ArrayList、Vector及Map、HashTable、HashMap。
Collection是List、Set两个接口的父接口,
List在Collection上增加了“有序”的特性,而set增加了“唯一”的特性;
Arraylist是有序不唯一的;
Vector(向量类)可以实现类似动态数组的功能,但是又区别于C语言中的概念,因为Java中是不存在“指针”这一概念,相对于Arraylist而言,Vector线程是安全的,也就是说是支持线程同步的,创建了一个Vector类的对象后,可以往其中随意地插入不同的类的对象,既不需顾及类型也不需预先选定向量的容量,并可方便地进行查找;
Map不能包括两个相同的键,它是无序的,但是Map的值是可以重复的;
Hashtable是Dictionary类的子类,缺省是线程同步的,不允许关键字或值为null;HashMap是Map接口的实现类,缺省情况下是非同步的。

Set和List的区别?

List接口对Collection进行了简单的扩充,它的具体实现类常用的有ArrayList和LinkedList。你可以将任何东西放到一个List容器中,并在需要时从中取出。
ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。
Set接口也是Collection的一种扩展,而与List不同的时,在Set中的对象元素不能重复,
也就是说你不能把同样的东西两次放入同一个Set容器中。
它的常用具体实现有HashSet和TreeSet类。HashSet能快速定位一个元素,但是你放到HashSet中的对象需要实现hashCode()方法。而TreeSet则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用到了集合框架提供的另外两个实用类Comparable和Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类具有相同的排序算法,那就不需要在每个类中分别重复定义相同的排序算法,只要实现Comparator接口即可。

集合框架中Collections和Arrays类的作用

集合框架中有两个很实用的公用类:
Collections和Arrays。Collections提供了对一个Collection容器进行诸如排序、复制、查找和填充等一些非常有用的方法,Arrays则是对一个数组进行类似的操作。

TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常!

(应该是没有针对问题的确切的答案),当前的add方法放入的是哪个对象,就调用哪个对象的compareTo方法(基于多态的理解),至于这个compareTo方法怎么做,就看当前这个对象的类中是如何编写这个方法的

数据结构中,数组与链表有哪些区别?为什么?

数组就像身上编了号站成一排的人,要找第10个人很容易,根据人身上的编号很快就能找到。但插入、删除慢,要望某个位置插入或删除一个人时,后面的人身上的编号都要变。当然,加入或删除的人始终末尾的也快。
链表就像手牵着手站成一圈的人,要找第10个人不容易,必须从第一个人一个个数过去。但插入、删除快。插入时只要解开两个人的手,并重新牵上新加进来的人的手就可以。删除一样的道理。