Java常见面试题_2022最新版
- Java常见面试题_2022最新版持续更新中…
一、集合容器面试题
常用的集合类有哪些
Collection
和 Map
接口是所有集合容器的父接口
常用的集合类:
Collection
接口List
接口ArrayList
LinkedList
CopyOnWriteArrayList
Set
接口HashSet
TreeSet
LinkedHashSet
Queue
接口Deque
Map
接口HashMap
TreeMap
ConcurrentHashMap
List,Set,Map的区别
- List,Set 是Collection的子接口
- List:
- 有序(存入集合的顺序和取出的顺序一致)
- 可以存储重复元素
- 常用的实现类有:ArrayList,LinkedList,Vector
- Set:
- 无序(存入元素和取出元素的顺序可能不一致),所以我们一般不以有序无序来作为Set的特点,它不同实现类不太一样,有的有序,有的无序
- 不可以存储重复元素
- 常用的实现类有:HashSet,LinkedHashSet,TreeSet
- List:
- Map 是一个键值对集合,存储键,值和之间的映射
- key 无序
- value 不要求有序,允许存放重复元素
集合和数组的区别
- 数组的长度是固定的,集合的长度是可变的
- 数组中既可以存储基本类型,也可以存储引用类型;
- 基本类型存的是值
- 引用类型存的是地址值
- 集合中只能存储引用类型
- 如果存储的是基本类型,会自动装箱成包装类
- 数组中只能存储同一种类型的元素,集合中可以存储不同类型的元素
Collection 和 Collections 的区别
- Collection 是集合框架的父级接口,提供了对集合对象进行基本操作的通用接口方法。Collection 为其子集合提供了一个统一的操作方式(向上造型);
- Collections 是一个工具类,他包含了很多操纵集合的静态方法,用于对集合中元素进行排序、搜索、线程安全等等操作;此类构造方法被 private 修饰,所以不能实例化,服务于 Collection 集合.
集合中哪些是安全的
- Vector
- CopyOnWriteArrayList
- HashTable
- ConcurrentHashMap
泛型的种类
-
<E>
通常在集合中使用- E
- Element
- E
-
<T>
通常表示类- T
- Type
- T
-
<K,V>
通常表示键值对- K
- Key
- V
- Value
- K
-
?
表示泛型通配符
(一)List
List 获取集合元素调用哪个API
list.size()
ArrayList 和 LinkedList 的区别
- ArrayList
- 数据结构:基于Object动态数组实现
- 随机访问效率(可以理解为查询效率,略微有些不同):效率高,直接可以通过下标进行访问
- 增删元素效率:增删元素效率较低,增删元素影响数组内的其他元素下标
- 内存占用空间:较低
- 线程安全:不同步,不保证线程安全
- LinkedList
- 数据结构:基于双向链表实现
- 随机访问效率(可以理解为查询效率,略微有些不同):线型数据存储方式,需要通过指针从前往后依次查询
- 增删元素效率:增删元素效率较高
- 内存占用空间:较高,每个节点除了存储元素之外,还存储2个引用,prev指向上一个节点,next指向下一个节点
- 线程安全:不同步,不保证线程安全
需要频繁读取集合中元素,我们一般使用ArrayList;插入和删除操作比较多时,使用LinkedList
ArrayList 和 Vector 的区别
ArrayList 和 Vector 都是 List 集合接口的实现类,他们底层都是数组这样的存储结构,它们都是有序集合。
Vector是 Java中的遗留容器,现在不怎么使用了
- 线程安全:Vector 使用了 Synchronized 来实现线程同步,是线程安全的,而 ArrayList 是非线程安全的。
- 性能:ArrayList 在性能方面要优于 Vector。
- 扩容机制:Vector扩容每次增加1倍,ArrayList扩容每次增加50%
List 是接口还是类,List 是怎么遍历的
List 是接口
List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
// 方法一
for(String s:list){ // 使用 foreach 循环
System.out.print(s);
}
// 方法二
for(int i=0;i<list.size();i++){ // 对于 ArrayList 来说速度比较快, 用 for 循环, 以 size 为条件遍历:
String str=list.get(i);
System.out.print(str);
}
// 方法三
Iterator<String> it=list.iterator(); // 集合类的通用遍历方式, 迭代器遍历
while(it.hasNext()){
System.out.print(it.next());
}
数组和集合(List)之间如何转换
// 数组转(ArrayList)集合 -- Arrays. asList(array)
String[] str = new String[]{"zs","ls","ww"};
List<String> strings = Arrays.asList(str)
// 集合(ArrayList)转数组
List<String> list = new ArrayList<>();
list.add("zs");
list.add("ls");
list.add("ww");
list.toArray();
循环遍历集合过程中如何删掉某个元素
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
list.add("邹七");
list.add("张三");
list.add("李四");
list.add("李四");
//切记,这里需要用迭代器删除,而不要使用list的remove方法
Iterator it = list.iterator();
while (it.hasNext()) {
String name = (String)it.next();
if ("李四".equals(name)) {
it.remove();
}
}
System.out.println(list);
错误案例:
for(Integer i : list){
list.remove(i); // 循环遍历的过程中,不能使用list.remove方法进行删除
}
(二)Set
如何给 ArrayList 去重(去除重复元素)
public static List duplicateList(List list) {
HashSet set = new HashSet();
set.addAll(list);
return new ArrayList(set);
}
public static void main(String[] args)() {
List list = new ArrayList();
list.add(new Integer(1));
list.add(new Integer(2));
list.add(new Integer(2));
list.add(new Integer(4));
list.add(new Integer(4));
List list2 = duplicateList(list);
System.out.println(list2)
}
HashSet实现原理
- HashSet 是基于 HashMap 实现的,默认构造一个初始容量为16,负载因子为0.75的 HashMap。封装了一个 HashMap 对象类存储所有的集合元素,所有放入 HashSet 中的集合元素实际上是由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT ,它是一个静态的 Object 对象。
- HashSet的操作都是基于HashMap的。
HashSet
// 与支持 Map 中的对象关联的虚拟值
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
HashMap
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
PRESENT 存在的意义
add
方法返回值为 boolean,表明当前添加的元素是否出现了重复
- 如果此 set 尚未包含指定元素,则返回 true(元素不重复)
- 如果此 set 尚包含指定元素,则返回 false(元素重复)
- 里面实际调用了
map.put(k,v)
,put 方法返回值情况有两种
- 如果 key 出现重复,返回上回存放的 value ,并进行覆盖
- 返回 PRESENT 对象,add 返回 false
- 如果第一次存放,put 返回的是 null
- add 返回 true
(三)Map
HashMap 底层原理
Java 中最常见的两种数据结构:数组,链表
数组:查询快,根据索引(下标)查询,插入删除慢
链表:查询速度慢,需要遍历整个链表,但是插入和删除快
HashMap 是数组和链表组成的,我们又称为散列表。
HashMap 基于 Hash 算法实现的,我们通过 put(key,value)存储,get(key)来获取值。
当传入 key 时,HashMap 会根据 key. hashCode() 计算出 hash 值,根据 hash 值将 value 保存。
当计算出的 hash 值相同时,我们称之为 hash 冲突,HashMap 的做法是用链表和红黑树存储相同 hash 值的 value。当 hash 冲突的个数比较少时,使用链表否则使用红黑树,当子节点大于等于 8 时使用红黑树。
HashMap 和 HashTable 有什么区别?
HashMap 是线程不安全的,HashMap 是 Map 的一个子接口,是将键映射到值得对象,不允许键值重复;允许空键和空值;由于非线程安全,HashMap 的效率要较 HashTable 的效率高一些。
HashTable 是线程安全的一个集合,不允许 null 值作为一个 key 值或者 Value 值;
HashTable 是 sychronize,多个线程访问时不需要自己为它的方法实现同步,而 HashMap 在被多个线程访问的时候需要自己为它的方法实现同步。
HashMap 遍历的所有方法
Set set = map.keySet()
Object value = map.get(key)
map.forEach((k,v) -> System.out.println(k+":"+v));
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
Collection values = map.values();
Map<String,Integer> map = new HashMap<>();
map.put("语文",99);
map.put("数学",98);
map.put("英语",97);
map.put("物理",96);
map.put("化学",99);
/*
遍历所有的key
Set<key> keySet()
将Map中所有的key存入一个Set集合后将其返回
*/
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println("key:"+key);
Integer value = map.get(key);
System.out.println("value: "+value);
}
-----------------------------------------------------
/*
Map也支持使用forEach方法遍历键值对
*/
map.forEach((k,v)-> System.out.println(k+":"+v));
-----------------------------------------------------
/*
遍历每一组键值对
Set<Entry> entrySet()
将当前Map中每组键值对以一个Entry实例表示并存入Set集合将其返回
*/
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
for(Map.Entry<String,Integer> e : entrySet){
String key = e.getKey();
Integer value = e.getValue();
System.out.println(key+":"+value);
}
-----------------------------------------------------
/*
遍历所有的value
Collection values()
将当前Map中所有的value以一个集合形式返回
*/
Collection<Integer> values = map.values();
values.forEach((e)->System.out.println("value:"+e));
HashMap 和 HashSet 的区别
-
HashMap
实现了Map
接口,HashSet
实现了Set
接口 -
HashMap
存储键值对,HashSet
存储对象 -
HashMap
添加元素put(key,value)
,HashSet
添加元素add(Element e)
-
HashMap
使用 key 来计算 hashcode,HashSet
使用成员对象计算 hashcode值,如果两个对象hashcode相同,比较equals方法来判断对象是否相等,不等返回false -
HashMap
比较快,HashSet
较慢 -
持久更新中…
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/107632.html