容器相关面试

1java 的容器都有哪些?

 

Java的容器 list ,map ,set

可以比较的点有 : 有序无序,

可重复不可重复,

键值是否可为null

底层实现的数据结构(数组、链表、哈希。。。)

线程安全性

2.collection 和collections 的区别是什么?

collection是一个jdk 中最根本的接口,定义了集合的基本方法

collections 一个包装类。它包含各种有关集合操作的静态多态方法,不能实例化。像一个collection集合框架中的工具类

3.hashmap 和hashtable 的区别

HashTable和HashMap的区别详解 - 割肉机 - 博客园

hashmap 是基于hash表实现的,每一个元素都是一个key-value 对对内部通过单链表解决冲突问题,容量不足(超过了阀值),同样会自动增长。

hashmap 是非线程安全的,只是用于单线程环境下,多线程环境下采用concurrent 并发包下下的concurrentHashMap.

hashmap 实现了serializable 接口,因此支持序列化,实现了cloneable 接口,能被克隆

【Java集合源码剖析】HashMap源码剖析_兰亭风雨的专栏-CSDN博客_hashmap 源码

hashtable 

 Hashtable同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。

      Hashtable也是JDK1.0引入的类,是线程安全的,能用于多线程环境中。

      Hashtable同样实现了Serializable接口,它支持序列化,实现了Cloneable接口,能被克隆。

【Java集合源码剖析】Hashtable源码剖析_兰亭风雨的专栏-CSDN博客_hashtable源码

(1)两者之间的区别: hashtable 继承自Dictionary  hashMap 继承自AbstractMap 类,但两者都实现了map 接口

(2)线程安全性不同,hashtable 是线程安全的,其方法是synchronize的,hashmap 的实现是不同步的,在多线程同事访问一个hash映射事件,而其中至少有一个线程从结构上修改了该映射,则它必须保持外部同步。

(3)是否提供contains 方法

 HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey,因为contains方法容易让人引起误解。

      Hashtable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同。

(4)key 和value是否允许null值 

(5)两个遍历方式的内部实现上不同

      Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

(6)hash值不同 

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

(7)内部实现使用的数组初始化和扩容方式不同

   HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。
      Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。

      Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。

4、如何决定使用 HashMap 还是 TreeMap?

TreeMap<k,v> 的key值要求实现java.lang.Comparable,所以迭代的时候treemap默认是按照升序来排序的,treemap的实现是基于红黑树结构,适用于按照自然顺序或者自定义顺序遍历键《key》

hashmap<k,v>的key值实现散列hashCode(),分布是散列的、均匀的、不支持排序;数据结构主要是桶(数组),链表或红黑树,适合在map中插入,删除,和定位元素。

因此,如果是想要得到一个有序的结果的时间使用treemap,

如何决定使用 HashMap 还是 TreeMap? - Java知音号 - 博客园

5.说一下 HashMap 的实现原理?

hashmap 使用的是数组加链表来进行实现的,每个数组中都储存着链表

当使用put方法储存key-value 键值对的时间,先使用key 的hashcode方法,得到key经过特定的哈希运算得到的值,然后通过其他运算(?)得到一个值,讲这个值与(length-1)做或操作(&),相当于对数组长度做取余操作,最终得到一个值作为key在数组中的索引值,然后将key-value 键值对储存进去,通过这种方法将储存的不同key-value 键值对“散列”到数组的不同位置

在存储的时间,如果索引位置尚无元素,则直接存储,如果有则调用此key的equals方法和原有的key 进行比较。如果返回true,说明在这个equls 定义的规则上,这两个key值相同,原有的key保留,用新的value 值代替原有的value。如果返回false,那么久说明这两个key在equals 定义的规则下是不同元素,那么就与此链表的下一个节点进行比较,直到最后一个节点都没有相同元素,再下一个是null的时候,就用头插法将此key-value值添加到链表中,

hashmap 对重复元素的处理方式是ke值不变,value覆盖

当使用get方法获取key对应的value时,会和储存key-value时用同样的方法,得到key在数组中的索引值,如果此索引值上没有元素,就返回null。如果此索引值上有元素,那么就拿此key的equals方法与此位置元素上的key进行比较,如果返回true。就返回此位置元素对应的value。如果返回false,就一直按链表往下比较,如果都是返回false,那么就返回null。
 

6.说一下 HashSet 的实现原理?

hashset 是基于hashmap 实现的,默认构造函数是构建一个初始容量为16,负载因子为0.75的hashmap,封装了一个hashmap来存贮所有的集合,所有放入hashset的集合元素实际上是由hashmap 的key来保存,而hashmap的value则存储一个present,他是一个静态的Objcet对象。

当我们试图将某个类的对象当成hashmap的key,或者试图将这个类的对象放入hashset中保存时,重写该类的equals方法和hashcode方法,而且这两个值必须保持一致:当该类的两个hashcode返回值相同时,他们通过equals()方法比较返回值为true,通常来说,所有参与计算hashcode()返回值得关键属性,都应该用作于equals比较的标准

hashset的其他操作都是基于hahsmap 来实现的

总结一下,hashset 是将hashmap 封装后形成的,在存储方式上与hashmap 不同,hashset 存储相同值的时间会将老的数据覆盖

Java面试题之HashSet 的实现原理?_马小_菜的博客-CSDN博客_说一下hashset的实现原理

7、ArrayList 与LinkList的区别

arrayList 原始长度为8成1.5倍速度增长

 1) ArrayList 底层是通过数组来实现的,LinkList 底层是通过双向链表来实现的,

2)ArrayList 在查上的效率更高一些,LinkList 在修改上效率更高,因为Arraylist 在进行增删改的时间要移动数据

底层

用大白话告诉你ArrayList的底层原理 - 我是村村的指挥官 - 博客园

8、如何实现数组和 List 之间的转换?

List转数组:toArray(arrayList.size())方法

数组转List: Arrays 的asList(a) 方法

public static void testArray2List() {
    String[] strs = new String[] {"aaa", "bbb", "ccc"};
    List<String> list = Arrays.asList(strs);
    for (String s : list) {
        System.out.println(s);
    }
}
public static void testList2Array() {
    List<String> list = Arrays.asList("aaa", "bbb", "ccc");
    String[] array = list.toArray(new String[list.size()]);
    for (String s : array) {
        System.out.println(s);
    }
}

如何实现数组和List之间的转换_yechengchao的博客-CSDN博客_list 转数组

9、ArrayList 和 Vector 的区别是什么?

两者底层都是长度可变的数组存储

区别有以下几点: 1同步性:vector是线程安全的,用synchronized实现线程安全,而ArrayList是线程不安全的,如果只有一个线程会访问集合,那最好使用ArrayList。2、数据容量增长,二者都有一个初始容量大小,采用线性连续存储空间,当存储的元素的个数超过容量是,就需要二者增加存储空间,Vector 增长为原来的一倍,ArrayList 增长为原来的0.5倍

ArrayList和Vector的区别_joli_1034498274的博客-CSDN博客_vector和arraylist的主要区别是

10Array 和ArrayList的区别

1.存储内容上的比较: Array 数组可以存储基本类型和对象类型,ArrayList 却只能包含对象类型;Array 在存储的时间一定是同种类型的元素,ArrayList 却不一定了。

2.空间大小比较 Array 数组的空间大小是固定的,ArrayList是动态数组,前者在事前就需要有合适的空间大小,后者是每次增加新元素的时间都要比较一下空间是否足够

3.方法的比较,ArrayList 方法上比Array更多样化,比如添加addAll()、删除removeAll(),返回迭代Iterator()等。

11.在 Queue 中 poll()和 remove()有什么区别?

poll 若果队列为空的时候,会抛出异常,而 remove() 只会返回null;

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

线程安全: 在多线程访问的时间,采用了加锁机制;既当一个线程访问该类的某个数据的时间,会对这个数据进行保护,其他线程不能对其进行访问,直到该线程读取完之后,其他线程才能使用,防止出现数据不一致或者数据被污染的情况

线程不安全:不提供数据访问时的数据保护,多个线程能够同时操作某个数据,从而出现数据不一致或者数据污染的情况。

对于线程不安全问题,一般会使用synchronized 关键字加锁同步控制。

线程安全的集合对象: vector hashTable stringBuffer

非线程安全的集合对象:

  • ArrayList :
  • LinkedList:
  • HashMap:
  • HashSet:
  • TreeMap:
  • TreeSet:
  • StringBulider:

13迭代器 Iterator 是什么?

迭代器首先是一种设计模式,用于顺序访问集合对象的元素,无需知道集合对象的底层实现。

Iterator 是可以遍历集合的对象,为各种容器提供了公共的操作接口,隔离对容器的遍历操作和底层实现,从而解耦。

缺点是增加新的集合类需要对应增加新的迭代器类,迭代器类与集合类成对增加

14.Iterator 怎么使用?有什么特点?

 Java中的Iterator功能比较简单,并且只能单向移动:

  (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

  (2) 使用next()获得序列中的下一个元素。

  (3) 使用hasNext()检查序列中是否还有元素。

  (4) 使用remove()将迭代器新返回的元素删除。

15Iterator 和 ListIterator 有什么区别?

一.相同点
都是迭代器,当需要对集合中元素进行遍历不需要干涉其遍历过程时,这两种迭代器都可以使用。

二.不同点
1.使用范围不同,Iterator可以应用于所有的集合,Set、List和Map和这些集合的子类型。而ListIterator只能用于List及其子类型。
2.ListIterator有add方法,可以向List中添加对象,而Iterator不能。
3.ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator不可以。
4.ListIterator可以定位当前索引的位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
5.都可实现删除操作,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改。
Iterator和ListIterator之间有什么区别?_不见风雨怎能见彩虹-CSDN博客_iterator和listiterator区别

16.怎么确保一个集合不能被修改?

我们可以采用Collections包下的unmodifiableMap方法,通过这个方法返回的map,是不可以修改的。他会报 java.lang.UnsupportedOperationException错。

同理:Collections包也提供了对list和set集合的方法。
Collections.unmodifiableList(List)
Collections.unmodifiableSet(Set)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值