zoukankan      html  css  js  c++  java
  • Java:Java集合系统整理

    1. 集合是做什么的?

    Java集合类位于Java.util包中,是一个用来存放对象的容器。

    2. Java集合框架

    2

    可以发现上述所有的集合类,除Map之外,都实现了Iterator接口。
    Iterator可用来遍历集合类,提供有hasNext(), next(), remove()三个方法;
    其子接口ListIterator在此基础上增加了add(), previous(), hasPrevious()三个方法。

    3. 面试题汇总

    3.1 List、Set、Map三者的区别?

    • List(对付顺序的好帮手): 存储的元素是顺序的,可重复的;
    • Set(注重独一无二的性质): 存储的元素是无序的,不可重复的;
    • Map(用key来搜索的专家): 使用键值对(key-value)存储,key是无序的,不可重复的;value是无序的,可重复的。

    3.2 ArrayList和LinkedList的区别?

    1)底层数据结构

    • ArrayList底层使用的是Object数组;
    • LinkedList底层使用的是双向链表(JDK1.6之前是循环链表,1.7之后取消了循环链表)。

    2)插入和删除是否受元素位置的影响

    • ArrayList会;
    • LinkedList不会。

    3)内存占用空间

    • ArrayList空间浪费主要体现在List结尾会预留一定的容量空间;
    • LinkedList空间浪费体现在每个节点需要存后继和前驱。

    4)是否支持快速随机访问

    • 随机访问是指通过元素的序号快速获取元素对象(对应于get(int index)方法)
    • ArrayList支持;LinkedList不支持。

    3.3 ArrayList和Vector的区别?

    • ArrayList是List的主要实现类,底层使用Object数组实现,是线程不安全的;
    • Vector是List的古老实现类,底层也使用Object数组实现,是线程安全的。

    3.4 HashMap和HashTable的区别?

    1)线程是否安全

    • HashMap线程不安全,想要线程安全的话使用ConcurrentHashMap;
    • HashTable线程安全,内部所有的方法基本都经过synchronized修饰。

    2)效率高

    • HashMap效率高;
    • HashTable基本被淘汰,不要在代码中使用它。

    3)null值

    • HashMap允许key和value为null值,key为null只能有一个,value为null可以有多个;
    • HashTable不允许有null值,否则会报异常。

    4)初始容量和每次扩充容量大小的不同

    • HashMap初始容量为16 ,扩容变为原来的2倍 ,创建时如果给定容量初始值,容量会成为设置容量的2的幂次方; -- HashMap总是使用2的幂作为哈希表的大小
    • HashTable初始容量为11 ,扩容每次扩为2n+1,创建时如果给定容量初始值,给定为几就是几。

    5)底层数据结构

    • Jdk1.8后HashMap扩容机制发生了较大变化,当链表长度大于阈值8(默认)时 ,先判断数组长度如果小于64先对数组进行扩容而不转换成红黑树,之后如果链表长度大于8则将链表转成红黑树;
    • HashTable没有这样的机制。

    3.5 HashMap和HashSet的区别?

    1)HashSet底层是基于HashMap实现的;
    2)HashMap实现Map接口,HashSet实现Set接口;
    3)HashMap存储键值对,HashSet存储不重复的对象;
    4)HashMap添加元素使用put,HashSet添加元素使用add;
    5)HashMap使用键计算hashCodeHashSet使用成员对象计算hashCode,两个对象可能成员对象相同,hashCode相同,使用equals来判断对象的相等性。

    3.6 HashSet如何检查重复?

    • 新来一个对象,HashSet先检查已存有的对象中是否包含新对象的hashCode,如果不包含,直接加入,如果包含,再equals()看是否相同,不相同则加入,相同则与已有对象重复,不加入这个对象。

    注意:hashCode重写与equals()重写问题。

    3.7 HashMap底层实现?

    1)JDK1.8之前

    • 底层是数组和链表;
    • 扰动函数(JDK1.7有四次扰动,JDK1.8有进行优化)计算出哈希值,通过(n-1)& hash值(?) 判断当前元素存放的位置;
    • 如果当前位置存有元素,判断已存有和准备存入的元素哈希值和key 是否相同,如果相同,覆盖,如果不同,拉链法解决冲突。

    2)JDK1.8之后

    • 解决哈希冲突时有了较大变化:
    • 当链表长度大于默认阈值8时,先判断此时数组长度是否小于64,小于64则先对数组扩容(原来的2倍),否则将链表转换成红黑树,减少搜索时间。

    TreeMap、TreeSet、JDK1.8之后的HashMap底层都用到了红黑树;
    红黑树是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成线性结构。

    3.8 HashMap的长度为什么是2的幂次方?

    1)Hash值的范围-2147483648到2147483647,前后加起来大概40亿的映射空间,一般应用是很难出现碰撞的。问题是一个40亿长度的数组,内存是放不下的;
    2)所以这个散列值用之前还要先做对数组的长度取模运算,余数为对应的数组下标。数组下标 =(n-1)& hash(n代表数组长度);
    3)hash%length==hash&(length-1)成立的前提是length是2的n次方(why?);
    4)二进制位操作符&相对于%能提高运算效率。

    3.9 ConCurrentHashMap和HashTable的区别?

    1)底层数据结构不同

    • JDK1.7的ConcurrentHashMap底层为分段的数组+链表;JDK1.8之后ConcurrentHashMap与HashMap结构相同,数组+链表/红黑树,与HashMap基本相同;
    • HashTable和JDK1.8之前的HashMap结构类似底层是数组(主体)+链表(解决哈希冲突)

    2)线程安全实现的方式不同

    • ConcurrentHashMap在JDK1.7时,分段锁对数组进行分割分段,没把锁只锁数组中一部分数据。1.8之后,摒弃了段的概念,直接用Node数组+链表/红黑树,并发控制使用synchronized和CAS。整体看起来像是优化过且线程安全的HashMap,尽管JDK1.8中还可以看到段,但已简化其属性,仅是为了兼容旧版本。
    • HashTable是同一把锁,效率低下。

    3.10 ConCurrentHashMap线程安全的具体实现方式/底层具体实现?

    1)JDK1.7

    • 数据分成一段一段存储,每个数据段配一把锁,当线程占用锁访问一个数据段时,其他数据段可以被另一个线程访问;
    • ConcurrentHashMap = Segment + HashEntry: Segment实现了ReentrantLock,是一种可重入锁。HashEntry用于寸键值对数据。
    • 一个ConcurrentHashMap包含一个Segment,Segment结构与HashMap类似(数组+链表),每个Segment守护一个HashEntry(链表结构元素),修改HashEntry首先要获得Segment的锁。

    2)JDK1.8

    • ConcurrentHashMap取消了Segment分段锁,改用CAS和synchronized来保证并发安全。数据结构跟JDK1.8的HashMap类似。
    • Synchronized只锁定当前链表或红黑树的首节点,这样只要不出现Hash冲突,就不会并发,效率提升了N倍。

    3.11 比较HashSet、LinkedHashSet和TreeSet三者的异同?

    • HashSet是Set的实现类,底层使用HashMap,是线程不安全的,可以存储null值;
    • LinkedHashSet是HashSet的子类,可以按添加顺序遍历;
    • TreeSet是Set的实现类,底层是红黑树,可以按照添加的顺序遍历,排序的方式有自然排序和定制排序。

    参考链接:

    https://www.cnblogs.com/lixiansheng/p/11348050.html
    JavaGuide

    步履不停
  • 相关阅读:
    linux getch()实现
    cppcheck 下载与安装(Liunx)
    apt-get 命令
    nanopb 文档
    VS调试技术
    c 单元测试 check
    GDB 调试
    GCC选项 –I,-l,-L
    作业66
    zhuoye
  • 原文地址:https://www.cnblogs.com/yuanyunjing/p/15162437.html
Copyright © 2011-2022 走看看