1. java 容器都有哪些?
答:List、Set、Map
2. Collection 和 Collections 有什么区别?
答:Collection是集合类的顶级接口,其派生了两个子接口 Set 和 List。Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。
3. List、Set、Map 之间的区别是什么?
答:
List | Set | Map |
---|---|---|
可以允许重复对象 | 不允许重复对象 | 值可以相同但键必须是唯一 |
可以插入多个null元素 | 只允许一个null元素 | 值可以多个null但键只能有一个null |
有序容器 | 无序容器 | 无序容器 |
4.HashMap 和 Hashtable 有什么区别?
HashMap | Hashtable | |
---|---|---|
存储 | key和value可以为null | key和value不能为null |
线程安全 | 非线程安全 | 线程安全 |
速度 | 快 | 慢 |
5.如何决定使用 HashMap 还是 TreeMap?
答:对于在 Map 中插入、删除、定位一个元素这类操作,HashMap 是最好的选择,因为相对而言 HashMap 的插入会更快,但如果你要对一个 key 集合进行有序的遍历,那 TreeMap 是更好的选择。
6.说一下 HashMap 的实现原理?
答:https://www.cnblogs.com/yuanblog/p/4441017.html
7.说一下 HashSet 的实现原理?
答:https://www.cnblogs.com/skillking/p/7250606.html
8.ArrayList 和 LinkedList 的区别是什么?
答:ArrayList 是线性表,底层是使用数组实现的,它在尾端插入和访问数据时效率较高。
LinkedList 是双向链表,它在中间插入或者插入时效率较高,在访问数据时效率较低。
9.如何实现数组和List 之间的转换?
String[] array = new String[12];
List<String> list = Arrays.asList(array);
String[] array1 = list.toArray(new String[list.size()]);
10.ArrayList 和 Vector 的区别是什么?
1)Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
2)当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
11.Array 和 ArrayList 有何区别?
答:Array 与 ArrayList 都是用来存储数据的集合。ArrayList 底层是使用数组实现的,但是ArrayList对数组进行了封装和功能扩展
12.在 Queue 中 poll()和 remove()有什么区别?
public interface Queue<E> extends Collection<E> {
/*
* add方法,在不违背队列的容量限制的情况,往队列中添加一个元素, 如果添加成功则返回true, 如果因为容量
* 限制添加失败了,则抛出IllegalStateException异常
*
* 在有容量限制的队列中,最好使用offer方法
* 另外,add方法相对与offer方法而言,有一个专门抛出的异常IllegalStateException,代表由于容量限制,
* 导致不能添加元素的异常,接口中可能看不出,等看具体实现就明白了
*/
boolean add(E e);
/*
*
* offer方法在不违背容量限制的情况,往队列中添加一个元素,如果添加元素成功,返回true,
* 如果因为空间限制,无法添加元素则,返回false;
*
* 在有容量限制的队列中,这个offer方法优于add方法,结合上文中add的注释,可知,
* 在容量限制的队列中, add方法通过抛异常的方式表示容量已满,offer方法通过返回
* false的方式表示容量已满,抛异常处理更加耗时,offer直接返回false的方式更好
*
*/
boolean offer(E e);
/*
* 删除队列头的元素,这个方法和poll方法的不同之处在于,这个方法在队列为
* 空的时候选择抛异常
*
*/
E remove();
/*
* poll方法也是删除队列头的远,如果队列为空的化,返回null
*
*/
E poll();
/*
* 返回队列头元素,这个方法和peek方法的区别在于,入股队列为空,将抛异常
*
*/
E element();
/*
* 返回队列头元素,如果队列为空,将返回空
*
*/
E peek();
}
13.哪些集合类是线程安全的?
答:Vector、HashTable
14.迭代器 Iterator 是什么?
答:Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包括了可以返回迭代器实例的迭代方法。迭代器可以在迭代过程中删除底层集合的元素,但是不可以直接调用集合的remove(Object obj)删除,可以通过迭代器的remove()方法删除
15.Iterator 怎么使用?有什么特点?
- Iterator遍历集合元素的过程中不允许线程对集合元素进行修改,否则会抛出ConcurrentModificationEception的异常。
- Iterator遍历集合元素的过程中可以通过remove方法来移除集合中的元素。
- Iterator必须依附某个Collection对象而存在,Iterator本身不具有装载数据对象的功能。
- Iterator.remove方法删除的是上一次Iterator.next()方法返回的对象。
- 强调以下next()方法,该方法通过游标指向的形式返回Iterator下一个元素。
16.Iterator 和 ListIterator 有什么区别?
- iterator()方法在set和list接口中都有定义,但是ListIterator()仅存在于list接口中(或实现类中);
- ListIterator有add()方法,可以向List中添加对象,而Iterator不能
- ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
- ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
- 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。
17.怎么确保一个集合不能被修改?
答:可以使用Collections.unmodifiableXXX或者Guava中的ImmutableXXX。
18. Hash算法的原理
哈希算法又叫散列算法,是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
常用的构造散列函数的方法:
- 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a?key + b,其中a和b为常数(这种散列函数叫做自身函数)
- 数字分析法:分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
- 平方取中法:取关键字平方后的中间几位作为散列地址。
- 折叠法:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。
- 随机数法:选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。
- 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p, p《=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。