1 Star 0 Fork 31

阿明 / Ebooks

forked from Java精选 / Ebooks 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
2021年Java集合面试题大汇总附答案.md 9.94 KB
一键复制 编辑 原始数据 按行查看 历史

2021年Java集合面试题大汇总附答案

全部面试题答案,更新日期:01月30日,直接下载吧!

下载链接:高清500+份面试题资料及电子书,累计 10000+ 页大厂面试题 PDF

Java 集合

题1:Java 中两个对象 hashCode 相等会产生什么问题?

Java中两个对象hashCode相等会产生哈希碰撞,若key值相同则替换旧值,不然链接到链表后面,链表长度超过阙值8就转为红黑树存储。

题2:Java 中 List 和 Array 如何相互转换?

List to Array

List 提供了toArray的接口,所以可以直接调用转为object型数组

List<String> list = new ArrayList<String>();
Object[] array=list.toArray();

上述方法存在强制转换时会抛异常,下面此种方式更推荐:可以指定类型

String[] array=list.toArray(new String[list.size()]);

Array to List

最简单的方法

String[] array = {"java", "c"};
List<String> list = Arrays.asList(array);

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

题3:HashMap 长度为什么是2的幂次方?

HashMap默认长度16,扩容是2的n次方。

HashMap为了存取高效,要尽量较少碰撞,通俗的说就是要尽量把数据分配均匀,每个链表长度大致相同,这个实现就是要把数据存到哪个链表中的算法。

取模即hash%length,计算机中直接求余效率不如位移运算,JDK源码中做了相应的优化hash&(length-1),hash%length==hash&(length-1)的前提是length是2的n次方;

比如说10%8=2,10的二进制是1010,8的二进制是0100

0000 1010 0000 1000

这种取余操作对应2的幂次实际上也就是除数的值之前的数据被整除,后面的余数就是被除数剩余部分为1的值。

0000 1010除以0000 1000把0000 1000高位以及自己抹除,剩下0000 0010。换成与(&)的操作,就是把n(除数)-1和被除数,取余的结果“(n-1)&hash ”。

为什么这样可以均匀分布减少碰撞呢?

2的n次方实即为1后面有n个0,2的n次方-1即为n个1;

比如长度为9时,3&(9-1)=0  2&(9-1)=0 ,都在0上,碰撞了;

比如长度为8时,3&(8-1)=3  2&(8-1)=2 ,不同位置上,不碰撞。

其实就是按位“与”的时候,每一位都能&1,也就是和1111……1111111进行与运算。

Hash值的范围值-2147483648到2147483647,前后加起来大概40亿的映射空间,只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但问题是内存是无法存储这种量级别数组的,所以这个散列值是不能直接使用的。可以针对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是“(n-1) & hash”。这也就解释了HashMap的长度为什么是2的幂次方。

题4:Java 中两个键 hashCode 相等,如何获取对象?

HashCode相同,通过equals比较内容获取值对象。

题5:HashMap 参数 loadFacto 作用是什么?

loadFactor表示HashMap的拥挤程度,影响hash操作到同一个数组位置的概率。默认loadFactor等于0.75,当HashMap里面容纳的元素已经达到HashMap数组长度的75%时,表示HashMap太挤了,需要扩容,在HashMap的构造器中可以定制loadFactor。

题6:Collection 和 Collections 有什么区别?

java.util.Collection是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java类库中有很多具体的实现。

Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。其直接继承接口有List与Set。

Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set

java.util.Collections是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

题7:HashMap 集合如何按 value 值排序?

HashMap是一个数组和链表组成的一种链表散列结构,存储方式是根据key的hash值来决定存储的位置,因此存储后的元素不会维持插入时的顺序。

如果需要控制某个类的次序且本身不支持排序,可以通过java.util.Comparator接口建立一个类比较器进行排序从而实现排序。

将HashMap中的entryset取出放入一个ArrayList中,对ArrayList中的entryset进行排序,以达到对HashMap中value值排序的效果。

实例代码如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class SortHashMap {
	public static void main(String[] args) {
	
		Map<String, Integer> map = new HashMap<>();
		map.put("A", 4);
		map.put("B", 2);
		map.put("C", 1);
		map.put("D", 3);

		List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
			@Override
			public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
				return o1.getValue() - o2.getValue();
			}
		});

		Iterator<Map.Entry<String, Integer>> iter = list.iterator();
		while (iter.hasNext()) {
			Map.Entry<String, Integer> item = iter.next();
			String key = item.getKey();
			int value = item.getValue();
			System.out.println("键:" + key + "   值:" + value);
		}
	}
}

执行结果如下:

键:C   值:1
键:B   值:2
键:D   值:3
键:A   值:4

题8:泛型都有哪些规则?

1、泛型的参数类型只能是类(包括自定义类),不能是简单类型。

2、同一种泛型可以对应多个版本,这是因参数类型是不确定的,不同版本的泛型类实例是不兼容的。

3、泛型类型的参数可以有多个。

3、泛型的参数类型可以使用extends语句,称为“有界类型”。

4、泛型的参数类型可以是通配符类型,例如Class类。

题9:Java 中 ConcurrentModificationException 异常出现的原因?

public class Test {
    public static void main(String[] args)  {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(2);
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            Integer integer = iterator.next();
            if(integer==2)
                list.remove(integer);
        }
    }
}

执行上段代码是有问题的,会抛出ConcurrentModificationException异常。

原因分析:调用list.remove()方法,导致modCount和expectedModCount的值不一致。

final void checkForComodification() {
    if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
}

解决办法:在迭代器中如果要删除元素的话,需要调用Iterator类的remove方法。

public class Test {
    public static void main(String[] args)  {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(2);
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            Integer integer = iterator.next();
            if(integer==2)
                iterator.remove();   //注意这个地方
        }
    }
}

题10:Java 中如何优化 ArrayList 集合插入万条数据量?

ArrayList的底层是数组实现且数组的默认值是10,如果插入10000条要不断的扩容,耗费时间,所以我们调用ArrayList的指定容量的构造器方法ArrayList(int size) 就可以实现不扩容,就提高了性能。

题11:hashmap-和-hashtable-有什么区别

题12:jdk1.8-中对-hashmap-和-concurrenthashmap-做了哪些优化

题13:set-为什么是无序的

题14:java-中如何判断-“java.util.linkedlist”-字符串实现-list-接口

题15:java-中什么是-fail-safe

题16:什么是-hashset

题17:jdk1.8-和-jdk1.7-中-arraylist-的初始容量多少

题18:hashset-和-hashmap-有什么区别

题19:为什么不直接将key作为哈希值而是与高16位做异或运算

题20:java-中如何实现单链表的反转

题21:arraylist-和-linkedlist-有什么区别

题22:java-中同步集合与并发集合有什么区别

题23:java-中求单链表中节点的个数

题24:java-数组中可以使用泛型吗

题25:java-中如何查找单链表中的中间结点

大厂面试题

大厂面试题

大厂面试题

Java
1
https://gitee.com/AminDev/ebooks.git
git@gitee.com:AminDev/ebooks.git
AminDev
ebooks
Ebooks
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891