Java面试题02(每次10道)

166 阅读2分钟

11、说一下 HashSet 和HashMap的实现原理?还有什么处理哈希冲突的方法?

关键字:HashMap是数组 + 链表;HashSet相当于HashMap的key,值是present

HashMap是基于哈希表的map接口的非同步实现。

HashMap的底层式一个数组 + 链表。先根据key的值通过hash算法计算出它的hash值,然后放在数组中的对应位置。如果该位置没有元素,那么把值放入该位置。如果该位置有元素,那么通过equals比较二者是否相等,如果不等那么就以链表的形式在该位置存储元素,如果相等,那么这个值就是重复的,不能放里面。

JDK8以后对HashMap进行了优化,当链表长度大于8的时候,底层会从链表变为红黑树。

HashSet相当于存储了HashMap的key一列,value值统一为present。

for (int i=0; i<size; i++) {
    @SuppressWarnings("unchecked")
    E e = (E) s.readObject();
    map.put(e, PRESENT);
}

12、JDK1.8中HashMap为什么当链表长度大于等于8时会转成红黑树?

HashMap中的key就是普通的值,而value进行排序,当链表长度超过8时,就会使用红黑树。为什么要使用使用红黑树,因为二叉树的查找非常方便,时间复杂度只有O(Log n),而链表为O(n),但是红黑树的存储会耗费很多内存,如果链表长度不达到一定规模的话,使用红黑树是不划算的。

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

如下图:

List-->数组 toArray

public static void main(String[] args) {
    List<Integer> intList = new ArrayList<>();
    intList.add(11);
    intList.add(12);
    intList.add(13);
    intList.add(14);
    System.out.println(Arrays.toString(intList.toArray()));
}

数组-->链表 asList

public static void main(String[] args) {
    Integer[] arr = {1,2,5,7};
    List<Integer> integerList = Arrays.asList(arr);
    integerList.forEach(ints -> System.out.println(ints));
}

14、Files的常用方法

增删改查。createFile、createDirectory、write、delete、move、size、write、copy、exists

15、hashcode相同的对象一定equals吗

不一定,因为hashcode是通过hash算法计算出来的,但是它可能有重复,还需要比较equals方法,但是equals的两个对象的hash值一定相等。

16、Collection和Collections

一般来说名称相同的两个类,一个是有s的,那么这个类大概率就是工具类。所以Collection是一个集合的顶级接口,它里面包含很多方法,比如add、isEmpty、remove等方法。

Collections是工具类其中包含很多辅助方法,比如搜索、排序、线程安全的方法。

17、Queue中的poll和remove方法

poll方法是从队列中弹出头部元素,如果队列为空的话,poll方法只会弹出null,而remove则会弹出NoSuchElementException方法。

18、迭代器Iterator是什么,怎么使用

Iterator是一个对象,它其中有next和hasNext方法,可以方便我们遍历集合中的数据。它指向的是集合的前一个元素,使用hasNext判断下一个值是否有值,如果有值那就返回下一个元素。

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(10);
    list.add(12);
    list.add(13);
    list.add(33);
    list.add(32);
    list.add(112);
    Iterator iterator = list.iterator();
    while (iterator.hasNext()){
        System.out.println(iterator.next());
    }
}

19、Iterator和ListIterator有什么区别?

ListIterator接口继承了Iterator接口,并增加了很多关羽List的方法。

Iterator可以遍历Set和List,而ListIterator只能遍历。

Iterator只能前向遍历,ListIterator可以后向遍历。

20、怎么确保一个集合不能被修改

可以通过Collections.unmodifibleCollection(Collection c);

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(10);
    list.add(12);
    list.add(13);
    list.add(33);
    list.add(32);
    list.add(112);
    Collection<Integer> list1 = Collections.unmodifiableCollection(list);
    list1.add(11);
}

报如下错误(unsupportedOperationException):

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.Collections$UnmodifiableCollection.add(Collections.java:1057)
	at util.StringTest.main(StringTest.java:15)