面试题之Java集合

集合的框架构成图

 

1、Iterator(迭代器)接口:它是java.util包的顶级接口(但是它不是Map系列的顶级接口)。迭代器遍历方式, 适用于连续内存存储方式,比如数组、 ArrayList(其实 ArrayList底层实现也是数组形式)。 缺点是只能从头开始遍历, 优点是可以边遍历边删除;可以实现Iterator接口可以增强for循环。

Iterator接口的方法:

(1)、hasNext():是否存在下一项;

(2)、next():获取下一项;

(3)、remove():该方法可以删除由next()最新返回的项;(注意:不能直接调用remove(),必须要在next方法调用之后调用);

(4)、void forEachRemaining(Consumer action):使用Lambda表达式来遍历集合元素,这是java8为Iterator新增的默认方法

 

2、Collection接口:它是ListSetQueue接口的父接口,它也是Iterator接口的子接口。

Collection接口方法:

(1)、size():返回集合的项数;

(2)、isEmpty():判断集合中是否为空;

(3)、contains(Object):判断集合中是否包含某项;

(4)、clear() 移除此 collection 中的所有元素(可选操作)。

(5)、add(E):从集合中添加某项;

(6)、remove(Object):从集合中删除某项;

(7)、Iterator():遍历集合;

 

在上面的集合中出现了remove()方法,竟然有相同的方法,那就有区别了。

问题1:Collection接口的remove()方法和Iterator接口的remove()方法区别?

①性能方面

    Collection的remove方法必须首先找出要被删除的项,找到该项的位置采用的是单链表结构查询,单链表查询效率比较低,需要从集合中一个一个遍历才能找到该对象;

    Iterator的remove方法结合next()方法使用,比如集合中每隔一项删除一项,Iterator的remove()效率更高

②容错方面

    在使用Iterator遍历时,如果使用Collection的remove则会报异常,会出现ConcurrentModificationException,因为集合中对象的个数会改变而Iterator 内部对象的个数不会,不一致则会出现该异常

    在使用Iterator遍历时,不会报错,因为iterator内部的对象个数和原来集合中对象的个数会保持一致

通过代码测试区别:

public void test1(){
    List list-new ArrayList();
    for(int i=0;i<10;i++){
        list.add(i);

    }

    Iterator iterator = list.iterator(); 
    while(iterator.hasNext()){
       Object o = iterator.next();
//      iterator.remove(); //不会出现异常
       list.remove(o); //会出现异常
        
    }

}

3、List接口:它是collection下的其中一个子接口。它的特点:可以添加重复的元素,添加的那些元素是有顺序的。在list接口下也有子接口分别是:ArrayList和LinkedList。

3.1、ArrayList:实现了所有可选列表操作,并允许包括 null 在内的所有元素。还提供一些方法来操作内部用来存储列表的数组的大小。

ArrayList的优缺点:

优点:

1、根据下标遍历元素效率较高。

2、根据下标访问元素效率较高。

3、在数组的基础上封装了对元素操作的方法。

4、可以自动扩容。

缺点:

1、插入和删除的效率比较低。

2、根据内容查找元素的效率较低。

扩容规则:每次扩容现有容量的50%。

LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。 LinkedList 实现 List 接口,能对它进行队列操作。

LinkedList的优缺点:

优点:在于删除和添加数据所消耗的资源较少,且比ArrayList效率高。 
缺点:线程不安全,查找消耗的资源大,效率低,不能随机访问。

问题2:ArrayList和LinkList的区别:

ArrayList(数组结构):

        优点:get和set调用花费常数时间,也就是查询的速度快;

        缺点:新项的插入和现有项的删除代价昂贵,也就是添加删除的速度慢

LinkedList(链表结构):

        优点:新项的插入和和现有项的删除开销很小,即添加和删除的速度快

        缺点:对get和set的调用花费昂贵,不适合做查询

通过代码测试区别:

public void test2(){
// 比较添加方面
    ArrayList arraylist = new ArrayList();
    LinkedList linkedlist=new LinkedList();

//给每个集合中添加5000条数据,比较时间
    for(int i=0 i<5000; i++){
        Object o=new Object();
        //arraylist.add(0,o);//耗时长
        linkedlist.add(0,o);//耗时短
    }
    long start=System.currentTimeMillis();
    //比较查询方面:
    for(int i=0;i<linkedlist.size();i++){
        //arrayList.get(i);//耗时短
          linkedlist.get(i);//耗时长
    }
    long end=System.currentTimeMillis();
    System.out.println("耗时:"+(end-start));

}

4、Set接口:特点:不保存重复数据,set是的数据是无序的。它的子接口:HashSet、TreeSet和LinkedSet。

4.1、HashSet:HashSet是set接口的实现类,也是我们最常用的set集合储存的是无序,唯一的对象由于是无序的所以每组数据都没有索引,两种遍历方法加强型for和迭代器,速度最块;没有明显的保存元素的顺序;不可重复;集合元素可以为 nullL,但只能放一个null。

4.2、TreeSet: 有序;不可重复;必须放入同样类的对象(默认会进行排序)。

4.3、LinkedHashSet:有序,不可以重复,因为底层采用 链表 和 哈希表的算法。链表保证元素的添加顺序,哈希表保证元素的唯一性。

问题3:HashMap、TreeMap、linkedHashMap区别?

可以从集合的使用场合回答面试官

①.在Map中插入、删除和定位元素,HashMap是最好的选择

②.需要集合有排序功能,使用TreeMap更好

③.需要按照插入的顺序存储集合,使用LinkedHashMap

可以从同异点回答面试官

相同点:

HashMap,LinkedHashMap,TreeMap都属于集合Map接口的子类。都是键值对集合。线程都不安全,效率高。

不同点:

(1)HashMap键是哈希表结构,可以保证键的唯一性,key能null,值也可为null。

(2)LinkedHashMap是HashMap的子类,内部依赖哈希表和链表列实现。由hash保证键的唯一性,由LinkedList保证有序性(存取顺序一致)。key能为Null,value也能为null。

(3)TreeMap类,键是红黑树结构,可以保证键的排序(自然排序),并且不能重复。key不能为null,value可以为null

可以在jdk方面回答

  jdk1.7及以下:Hashset是无序的,LinkedHashSet是怎么存怎么取,treeset有默认排序(comparable自然排序接口或comparator比较器接口)
    jdk1.8及以上:Hashset和treese都是有序的,HashSet的排序方式是散列排序(自身特殊的排列方式)  LinkedHashSet是怎么存怎么取,treeset有默认    排序    (comparable自然排序接口或comparator比较器接口)

共同点:1、都不允许元素重复

     2、都不是线程安全的类


5、Queue接口:俗称:队列,最先插入在元素将是最先被删除;反之最后插入的元素将最后被删除,因此队列又称为“先进先出”(FIFO—first in first out)的线性表。

扩展:既然有队列就要提一些相关的知识点了,就是Handler消息机制

Message: 消息对象 
Queen: 存储消息对象的队列 
Looper:负责循环读取MessageQueen中的消息,读到消息之后就把消息交给Handler去处理。 
Handler:发送消息和处理消息 

消息机制图片解析:

6、Mpa接口:key-value 的键值对,key 不允许重复,value 可以 

Map 集合即没有实现于 Collection 接口,也没有实现 Iterable 接口,所以不能对 Map 集合进行 for-each 遍历。

子接口包括 :HashMap、linkedMap与treeMap  特点跟set的差不多

7、arrays:用来操作数组(比如排序和搜索)的各种方法。包含一个允许将数组作为列表来查看的静态工厂。


问题4:Array与ArrayList有什么区别?

①Array是Java中的数组,声明数组有三种方式

int[] a=new int[10];

int a[]=new int[10];

int a[]={1,2,3,4};

可以看出:在定义一个数组的时候,必须指定这个数组的数据类型及数组的大小,也就是说数组中存放的元素个数固定并且类型一样

 

②ArrayList是动态数组,也就是数组的复杂版本,它可以动态的添加和删除元素,被称为”集合“,集合的声明如下

ArrayList list = new ArrayList(10);

ArrayList<Integer> list1 = new ArrayList<Integer>();

可以看出:在不使用泛型的情况下,这个list是可以添加进不同类型的元素的,而且arraylist是可以不用指定长度的。在使用泛型时,我们就只能添加一种类型的数据了

可以从三方面回答面试官

①.ArrayList是Array的复杂版本

②.存储的数据类型:Array只能存储相同数据类型的数据,而ArrayList可以存储不同数据类型的数据

③.长度的可变:Array的长度是固定的,而ArrayList的长度是可变的

问题5:怎样将一个数组转成List,有什么方法?

数组转list,可以使用Arrays.asList(数组),List转数组,使用list.toArray()。

问题6:HashSet、TreeSet、LinkedHashSet区别?

可以从集合的使用场合回答面试官

①.需要速度快的集合,使用HashSet

②.需要集合有排序功能,使用TreeSet

③.需要按照插入的顺序存储集合,使用LinkedHashSet

问题7:HashMap和HashSet区别

       

问题8:HashMap的实现原理

通过put和get存储和获取对象,存储对象时,我们将K/V传给put方法时,它调用hashcode计算hash从而得到bucket位置,进一步存储,HashMap会根据当前bucket的占用情况自动调整容量。获取对象时,我们将K传递给get,他调用hashcode计算hash从而得到bucket位置,并进一步调用equals()方法确认键值对。

问题9:List、Set、Map之间的区别

List和Set都继承Collection,但是Map不是Collection的子接口。

 

 

扩展:再来说一下怎么讲解项目
1.项目简介:
    该系统为XXX客户提供XXX服务平台(讲清楚它是干嘛的)
2.项目模块:
     模块1,2,3.... (让面试官了解项目有多大)  
3.责任描述:
     xx模块(核心模块), 讲明用**技术实现**功能
4.项目带来的收获:
(主要描述通过这个项目学到了以前不会的技术,突出项目带给你的帮助)
    比如:以前不太会**,通过做这个项目,给了我一次机会,玩的很熟了./**不会,通过这个项目 学会了
5.遇到的困难:
   描述解决方案,不说途径
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值