JAVA 关于JAVA集合在面试中可能遇见问题

集合:

在遍历Arraylist集合的时候,想要对性能上优化的话尽量使用for循环,少用foreach。因为对于for循环JVM只是简单地增加了一个整型变量,它直接从内存读值。这使它非常快。但forEach迭代则不同,JVM必须把forEach转换为迭代器并为每个数据项调用hashNext(),这就是为什么for循环比foreach快的原因。

而在LinkedList中,遍历还是用foreach或者迭代器,也可以使用removeFist()或者removeLast(),但是它们在遍历的时候回删除原数据。

 

arraylist集合查询快,添加删除慢

linkedlist添加删除快,查询慢

使用ArrayList集合的时候如果知道添加的数量,设置集合长度性能更好,如果数据近百万的话设置该数据的三分一长度,如果是十万级别的,设置该数据数量的长度即可。

 

Collection接口的remove()方法和Iterator接口的remove()方法区别?

①性能方面:

    Collection的remove方法必须首先找出要被删除的项,找到该项的位置采用的是单链表结构查询,

    单链表查询效率比较低,需要从集合中一个一个遍历才能找到该对象;

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

②容错方面:

    在使用Iterator遍历时,如果使用Collection的remove则会报异常,

    会出现ConcurrentModificationException,因为集合中对象的个数会改变而Iterator 内部对象的个数不会,

    不一致则会出现该异常,

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

 

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的长度是可变的

 

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

String[]str={"111","222","333"};

List<String> strings=Arrays.asList(str);

数组转成list之后不能进行add和remove的

如果需要的话,则:

List<String>newStrings=new ArrayList<String>(strings);

 

List转数组的方法:

List<String>str=new ArrayList<String>();

str.add("111");

str.add("222");

str.add("333");

String[] newString=str.toArray(new String[str.size]);

 

HashSet、TreeSet、LinkedHashSet区别?

当需要速度快的集合时使用HashSet.

需要集合有序的排序的时候使用TreeSet.

需要根据插入的顺序排序的时候使用LinkedHashSet.

 

HashMap、TreeMap、linkedHashMap区别?

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

需要有序的集合时使用TreeMap

需要按照插入顺序排序时使用linkedHashMap

 

HashMap和HashSet区别?

HashMap 实现了Map接口 存储键值对  调用put()向map中添加元素 HashMap使用key计算hashcode  HashMap相对于HashSet较快,因为它是使用唯一的键获取对象

 

HashSet  实现了Set接口 存储对象  调用add()向set中添加元素  HashSet使用成员对象计算hashcode  HashSet较HashMap来说比较慢

 

HashMap的实现原理?

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

 

HashMap的几个重要的信息:

默认大小为16( 2 的4次方)

扩容机制:当目前数超过总数的75%时扩展,扩展为原来的2倍,也就是2的n+1次方。

最大存2的30次方

 

List、Set、Map之间的区别?

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

List 可以允许重复的元素  可以插入多个null元素  有序的容器,插入的顺序和输出的顺序一样      

Set 不允许重复元素  只允许一个null元素 无序容器

Map 键值对存储,键必须唯一,但是值可以重复  键只允许一个null,值可以允许有多个null

无序容器

 

Map集合知识:

  1.   关于HashMap的一些说法: 
  2. a)  HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结构是一个数组,数组中的每一项是一条链表。 
  3. b)  HashMap的实例有俩个参数影响其性能: “初始容量” 和 装填因子。
  4.  c)  HashMap实现不同步,线程不安全。  HashTable线程安全 
  5. d)  HashMap中的key-value都是存储在Entry中的。 
  6. e)  HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals方法保证键的唯一性 
  7. f)  解决冲突主要有三种方法:定址法,拉链法,再散列法。HashMap是采用拉链法解决哈希冲突的。 注: 链表法是将相同hash值的对象组成一个链表放在hash值对应的槽位;    用开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。 沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。   拉链法解决冲突的做法是: 将所有关键字为同义词的结点链接在同一个单链表中 。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于1,但一般均取α≤1。拉链法适合未规定元素的大小。     
  8. 2.  Hashtable和HashMap的区别:                                                                                                                                  a)   继承不同。  public class Hashtable extends Dictionary implements Map 

public class HashMap extends  AbstractMap implements Map 

b)  Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。 

c)  Hashtable 中, key 和 value 都不允许出现 null 值。 在 HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null 。当 get() 方法返回 null 值时,即可以表示 HashMap 中没有该键,也可以表示该键所对应的值为 null 。因此,在 HashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey() 方法来判断。 

d)  两个遍历方式的内部实现上不同。Hashtable、HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

 e)  哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

 f)  Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。   注:  HashSet子类依靠hashCode()和equal()方法来区分重复元素。      HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值的,会去判断当前Map中是否含有该Key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同。 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值