热爱技术,追求卓越
不断求索,精益求精

Java面试经典基础问答七

1. List和Map的区别是什么?

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

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

List,Set是,Map不是。

3. 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多次时,即相当于集合中有多个索引指向了这个对象。List除了可以以Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以调用get(index i)来明确说明取第几个。
Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,objvalue),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key所对应的value。另外,也可以获得所有的key的集合,还可以获得所有的value的集合,还可以获得key和value组合成的Map.Entry对象的集合。

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

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

5. 如何去掉一个Vector集合中重复的元素?

/**
 * 遍历去重
 * @param vector
 * @return
 */
private static Vector<Object> removal1(Vector<Object> vector){
    Vector<Object> newVector = new Vector<Object>();
    for (int i=0; i< vector.size(); i++){
        Object obj = vector.get(i);
        if(!newVector.contains(obj)){
            newVector.add(obj);
        }
    }
    return newVector;
}

/**
 * set去重
 * @param vector
 * @return
 */
private static Vector<Object> removal2(Vector<Object> vector){
    HashSet<Object> set = new HashSet<Object>(vector);
    return new Vector<Object>(set);
}

6. Collection和Collections的区别是什么?

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

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

Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。equals()和==方法决定引用值是否指向同一对象,equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

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

最常用的集合类是 List、Set和 Map。 List的具体实现包括 ArrayList和 Vector、LinkedList它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。List适用于按数值索引访问元素的情形。Set里面不允许有重复的元素,具体实现有HashSet、TreeSet等。Map集合类用于存储元素对(称作”键”和”值”),其中每个键映射到一个值。List和Set都继承自Collection,有add、remove、size、retainAll、contains、containsAll、clear等方法;Map有put、get、size、remove、containsKey、containsValue等方法。

9. 两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

对。如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。如果不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如ArrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。

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

当前的add方法放入的是哪个对象,就调用哪个对象的compareTo方法,至于这个compareTo方法怎么做,就看当前这个对象的类中是如何编写这个方法的。当子类重写了父类的CompareTo方法时各自使用对应的compareTo方法,如果没有重写则调用父类的CompareTo方法。如果子类重写了父类的compareTo方法,如果先添加父类,再添加子类,可能会抛出异常。

package cn.lovecto.test;

import java.util.TreeSet;

public class Test {

    public static void main(String[] args) {
        //能正常添加
        TreeSet<Person> set1 = new TreeSet<Test.Person>();
        set1.add(new Cto(3, 1));
        set1.add(new Person(2));
        //会报java.lang.ClassCastException
        TreeSet<Person> set2 = new TreeSet<Test.Person>();
        set2.add(new Person(2));
        set2.add(new Cto(3, 1));
    }

    static class Person implements Comparable<Person> {
        int age;//年龄
        public Person(int age) {
            super();
            this.age = age;
        }
        @Override
        public int compareTo(Person o) {//比较的是人的年龄
            return this.age - o.getAge();
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }

    static class Cto extends Person {
        int salary;//薪资
        public Cto(int age, int salary) {
            super(age);
            this.salary = salary;
        }
        @Override
        public int compareTo(Person o) {//重写比较的是CTO的薪资
            return this.getSalary() - ((Cto)o).getSalary();
        }
        public int getSalary() {
            return salary;
        }
        public void setSalary(int salary) {
            this.salary = salary;
        }
    }
}
赞(4)
未经允许不得转载:LoveCTO » Java面试经典基础问答七

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

热爱技术 追求卓越 精益求精