写在最后
为了这次面试,也收集了很多的面试题!
以下是部分面试题截图
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素。Java SDK提供的类都是继承自Collection的“子接口”如List和Set。
如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
Iterator it = collection.iterator(); // 获得一个迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元素
}
由Collection接口派生的两个接口是List和Set。
四、Set
Set接口同样是Collection接口的一个子接口,Set不包含重复的元素。
HashSet:使用hashmap的一个集的实现。虽然集定义成无序,但必须存在某种方法能高效地找到一个对象。使用一个hashmap对象实现集的存储和检索操作时在固定时间内实现的。
TreeSet:在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap。
为优化hashset空间的使用,可以调优初始容量和负载因子。TreeSet 不包含调优选项,因为树总是平衡的,保证了插入、删除、查询的性能的高效。
当您要从集合中以有序的方式抽取元素时,TreeSet实现会有用处。为了能顺利进行,添加到TreeSet的元素必须是可排序的。
import java.util.*;
public class SetExample {
public static void main(String args[]) {
Set set = new HashSet();
set.add(“Bernadine”);
set.add(“Elizabeth”);
set.add(“Gene”);
set.add(“Elizabeth”);
set.add(“Clara”);
System.out.println(set);
Set sortedSet = new TreeSet(set);
System.out.println(sortedSet);
}
}
五、List
List接口继承了Collection接口,定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。
实际上有两种list:一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的LinkedList,它并不是快速随机访问设计的,而是具有更通用的方法。
-
List : 次序是List最重要的特点:它保证维护元素特定的顺序。
-
ArrayList : 由数组实现的List。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。
-
LinkedList : 对顺序访问进行了优化,向List中间插入与删除的开销并不大,随机访问则相对较慢。还具有下列方法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。
-
Vector:实现一个类似数组一样的表,自动增加容量来容纳你所需的元素。使用下标存储和检索对象就象在一个标准的数组中一样。你也可以用一个迭代器从一个Vector中检索对象Vector是唯一的同步容器类!!
-
stack:这个类从vector派生而来,并增加了方法实现栈,一种后进先出的存储结构。
List的用法示例:
package collection;
import java.util.*;
public class SetExample {
public static void main(String[] args) {
List linkedList = new LinkedList();
for (int i = 0; i <= 5; i++) {
linkedList.add(“a”+i);
}
System.out.println(linkedList);
linkedList.add(3,“a100”);
System.out.println(linkedList);
linkedList.set(6,“a200”);
System.out.println(linkedList);
System.out.println(linkedList.get(2));
System.out.println(linkedList.indexOf(“a3”));
linkedList.remove(1);
System.out.println(linkedList);
}
}
六、list和set对比
Set子接口:无序,不允许重复,检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List子接口:有序,可以有重复元素,和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
Set和List具体子类:
Set
|————HashSet:以哈希表的形式存放元素,插入删除速度很快。
List
|————ArrayList:动态数组
|————LinkedList:链表、队列、堆栈。
七、map
1、map接口不是Collection接口的继承。
不重复的键到值的映射。
2、Map.Entry 接口
map的entrySet()方法返回一个实现map.entry接口的对象集合。集合中每个对象都是底层map中一个特定的键值对。
3、HashMap 类和 TreeMap 类
在map中插入、删除和定位元素,HashMap是最好的选择。但如果您要按顺序遍历键,那么TreeMap 会更好。根据集合大小,先把元素添加HashMap,再把这种映射转换成一个用于有序键遍历的TreeMap 可能更快。
为了优化hashmap空间的使用,您可以调优初始容量和负载因子。这个treeMap没有调优选项,因为该树总处于平衡状态。
-
hashtable:实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类时前面Java实现的一个继承,并且通常能在实现映象的其它类中更好地使用。
-
hashmap:实现一个映象,运行存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个空)。
-
WeakHashMap:如果有一个键对于一个对象而言不再被引用,键将被舍弃,WeakHashMap在具有大量数据时使用。
-
TreeMap: 实现这样一个映象,对象是按键升序排列的。
4、map的使用示例
以下程序演示了具体map类的使用。该程序对自命令行传递的词进行频率计数。hashmap起初用于数据存储。后来,映射被转换为TreeMap以显示有序的键列列表。
package collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class MapExample {
public static void main(String[] args) {
String[] array = {“a”,“b”,“c”,“d”,“e”};
Map map = new HashMap();
Integer ONE = new Integer(1);
for (int i=0, n=array.length; i<n; i++) {
String key = array[i];
int frequency = i+1;
map.put(key, frequency);
}
System.out.println(map);
Map sortedMap = new TreeMap(map);
System.out.println(sortedMap);
//hashmap的同步
Map map1 = Collections.synchronizedMap(map);
System.out.println(map1);
}
}
5、控制台输出
八、HashMap、Hashtable、ConcurrentHashMap的原理与区别
1、HashTable
-
底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相关优化
-
初始size为11,扩容:newsize = olesize*2+1
-
计算index的方法:index = (hash & 0x7FFFFFFF) % tab.length
2、HashMap
-
底层数组+链表实现,可以存储null键和null值,线程不安全
-
初始size为16,扩容:newsize = oldsize*2,size一定为2的n次幂
-
扩容针对整个Map,每次扩容时,原来数组中的元素依次重新计算存放位置,并重新插入
-
插入元素后才判断该不该扩容,有可能无效扩容(插入后如果扩容,如果没有再次插入,就会产生无效扩容)
-
当Map中元素总数超过Entry数组的75%,触发扩容操作,为了减少链表长度,元素分配更均匀
-
计算index方法:index = hash & (tab.length – 1)
本次面试答案,以及收集到的大厂必问面试题分享:
5%,触发扩容操作,为了减少链表长度,元素分配更均匀
- 计算index方法:index = hash & (tab.length – 1)
本次面试答案,以及收集到的大厂必问面试题分享:
[外链图片转存中…(img-n7MiYJ0A-1714999370463)]