Java 集合概览

  • 从下图可以看出,在Java中除了以Map结尾的类之外, 其他类都实现了Collection接口。并且,以Map结尾的类都实现了Map接口

  • List、Set、Map三者的区别

    • List:存储的元素是有序的、可重复的
    • Set:存储的元素是无序的、不可重复的
    • Map:使用键值对(kye-value)存储,Key 是无序的、不可重复的,value 是无序的、可重复的,每个键最多映射到一个值
  • 集合底层数据结构

    • List

      • Arraylist: Object[]数组
      • Vector:Object[]数组
      • LinkedList:双向链表(JDK1.6之前为循环链表,JDK1.7取消了循环)
    • Set
      • HashSet(无序,唯一): 基于HashMap实现的,底层采用HashMap来保存元素
      • LinkedHashSet:LinkedHashSetHashSet的子类,并且其内部是通过LinkedHashMap来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 HashMap 实现一样,不过还是有一点点区别的
      • TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树)
    • Map
      • HashMapJDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间
      • LinkedHashMapLinkedHashMap继承自HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑
      • Hashtable:数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的
      • TreeMap: 红黑树(自平衡的排序二叉树)
  • Iterator: 迭代器,可以对集合进行遍历,但每一个集合内部的数据结构可能是不尽相同的,所以每一个集合存和取都很可能是不一样的,虽然我们可以人为地在每一个类中定义hasNext()next()方法,但这样做会让整个集合体系过于臃肿,于是就有了迭代器

    • 作用: 用来遍历集合用的,它的特点是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出ConcurrentModificationException异常
    • 使用:
   Map<Integer, String> map = new HashMap<>();
map.put(1, "Java");
map.put(2, "C++");
map.put(3, "PHP");
Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, String> entry = iterator.next();
System.out.println(entry.getKey() + entry.getValue());
}
  • 关于线程不安全的集合及解决方案

    • Arraylist,LinkedList,Hashmap,HashSet,TreeSet,TreeMapPriorityQueue都不是线程安全的
    • 解决方案:使用线程安全的集合
      • ConcurrentHashMap: 可以看作是线程安全的HashMap
      • CopyOnWriteArrayList: 可以看作是线程安全的ArrayList,在读多写少的场合性能非常好,远远好于Vector
      • ConcurrentLinkedQueue: 高效的并发队列,使用链表实现。可以看做一个线程安全的LinkedList,这是一个非阻塞队列
      • BlockingQueue: 这是一个接口,JDK内部通过链表、数组等方式实现了这个接口。表示阻塞队列,非常适合用于作为数据共享的通道
      • ConcurrentSkipListMap: 跳表的实现。这是一个Map,使用跳表的数据结构进行快速查找
  • ArraylistVector的区别

    • ArrayListList的主要实现类,底层使用Object[]存储,适用于频繁的查找工作,线程不安全
    • VectorList的古老实现类,底层使用Object[]存储,线程安全的。
  • ArraylistLinkedList的区别

    • ArrayListLinkedList都是不同步的,也就是不保证线程安全
    • Arraylist底层使用的是Object数组;LinkedList底层使用的是双向链表数据结构(JDK1.6 之前为循环链表,JDK1.7 取消了循环)
    • ArrayList采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响, LinkedList采用链表存储,所以对于add(E e)方法的插入,删除元素时间复杂度不受元素位置的影响,近似O(1),如果是要在指定位置i插入和删除元素的话((add(int index, E element)) 时间复杂度近似为o(n))因为需要先移动到指定位置再插入
    • LinkedList不支持高效的随机元素访问,而ArrayList支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)
    • ArrayList的空间浪费主要体现在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比 ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)

    扩展:双向链表和双向循环链表

  • comparable 和 Comparator 的区别

    • comparable接口实际上是出自java.lang包 它有一个compareTo(Object obj)方法用来排序
    • comparator接口实际上是出自java.util包它有一个compare(Object obj1, Object obj2)方法用来排序
  • 无序性和不可重复性的含义

    • 无序性不等于随机性 ,无序性是指存储的数据在底层数组中并非按照数组索引的顺序添加 ,而是根据数据的哈希值决定的
    • 不可重复性是指添加的元素按照 equals()判断时 ,返回 false,需要同时重写 equals()方法和 HashCode()方法
  • HashSetLinkedHashSetTreeSet三者的异同

    • HashSetSet接口的主要实现类 ,HashSet的底层是HashMap,线程不安全的,可以存储null
    • LinkedHashSetHashSet的子类,能够按照添加的顺序遍历
    • TreeSet底层使用红黑树,能够按照添加元素的顺序进行遍历,排序的方式有自然排序和定制排序。
  • HashMapHashtable的区别

    • HashMap是非线程安全的,HashTable是线程安全的,因为HashTable内部的方法基本都经过synchronized修饰
    • 因为线程安全的问题,HashMap要比HashTable效率高一点
    • HashMap可以存储nullkeyvalue,但null作为键只能有一个,null作为值可以有多个;HashTable不允许有null键和null 值,否则会抛出NullPointerException
    • 初始容量大小跟每次扩充容量大小不同:
      • 创建时如果不指定容量初始值,Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1HashMap默认的初始化大小为 16。之后每次扩充,容量变为原来的2
      • 创建时如果给定了容量初始值,那么Hashtable会直接使用你给定的大小,而HashMap会将其扩充为2的幂次方大小。也就是说HashMap总是使用 2的幂作为哈希表的大小
      • JDK1.8 以后的HashMap在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)(将链表转换成红黑树前会判断,如果当前数组的长度小于64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。Hashtable没有这样的机制

【java面试】- 集合篇的更多相关文章

  1. Java面试集合(七)

    前言: Java面试集合(六) 的回顾,对于final可以修饰常量,方法,和类,一旦常量定义好后就不可改变,而方法,用final来修饰方法,方法不可重载,继承,重写,final用来修饰类,该类不能被继 ...

  2. Java面试集合(三)

    前言 大家好,给大家带来Java面试集合(三)的概述,希望你们喜欢 三 1.在Java中是否可以含有多个类? 答:可以含有多个类,但只有一个是public类,public类的类名与文件名必须一致. 2 ...

  3. Java面试集合(二)

    前言 大家好,给大家带来Java面试集合(二)的概述,希望你们喜欢 二 1.请问线程有哪些状态? 新建状态(New) 就绪状态(Runnable) 运行状态(Running) 阻塞状态(Blocked ...

  4. Java面试集合(一)

    前言 大家好,给大家带来Java面试集合(一)的概述,希望你们喜欢 一 1.Java按应用范围可划分几个版本? 答:Java按应用范围有三个版本,分别是JavaSE,JavaEE,JavaME. 2. ...

  5. Java面试集合(三)-30道面试题

    前言 大家好,我是 Vic,今天给大家带来Java面试集合(三)的概述,希望你们喜欢 三 1.在Java中是否可以含有多个类?答:可以含有多个类,但只有一个是public类,public类的类名与文件 ...

  6. Java面试集合(六)

    1. abstract抽象 什么是abstract,中文为抽象,从具体事物抽出,概括它们共同的方面,本质属性与关系等,称为抽象.看不见,摸不着的东西叫做抽象,抽象是人们对世界万物的感觉,用特定的图像表 ...

  7. Java面试人事篇(二)

    1.请你自我介绍一下你自己? 回答提示:一般人回答这个问题过于平常,只说姓名.年龄.爱好.工作经验,这些在简历上都有.其实,企业最希望知道的是求职者能否胜任工作,包括:最强的技能.最深入研究的知识领域 ...

  8. java面试基础篇(一)

    最近想深入的理解一下java 的工作机制,也是便于后期的面试. 1.A:HashMap和Hashtable有什么区别? Q:HashMap和Hashtable都实现了Map接口,因此很多特性非常相似. ...

  9. java面试基础篇(二)

    上一篇,我们说了一下线程和Map,或许那些太抽象,不太好理解,也不太方便记忆,我们这次说一些简单的. 1.Q:java的基本数据类型有哪些? A:四种整数类型(byte.short.int.long) ...

  10. Java面试框架篇(8)

    71,谈谈你对Struts的理解. 1. struts是一个按MVC模式设计的Web层框架,其实它就是一个Servlet,这个Servlet名为ActionServlet,或是ActionServle ...

随机推荐

  1. JavaWeb网上图书商城完整项目--25.注册页面之隐藏没有内容的错误信息实现

    在上一章中我们显示的效果如下所示: 上面后面都有错误的红色×的显示,这样是不对的,我们要解决该问题 我们要循环遍历每一个错误的信息,看它的内容有没有,如果有内容我们就显示错误的×,如果没有就不显示× ...

  2. leetcode125. 验证回文串 python 简单

    125. 验证回文串 难度简单     给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写. 说明:本题中,我们将空字符串定义为有效的回文串. 示例 1: 输入: &quo ...

  3. SDL软件安全读书笔记(一)

    # 如何应对当前的全球网络安全威胁? 开发安全漏洞尽可能少的软件,应该着眼于源头安全. 边界安全盒深度防御是重要的安全手段,但软件自身的安全是安全防护的第一关. 即使软件源头存在较少的漏洞,这些漏洞也 ...

  4. 《算法笔记》6.6小节 问题 A: 任务调度

    这道题我一开始看到的时候,想到的是拓补排序,可是这么菜又这么懒的我怎么可能用呢,既然出现在优先队列里面,那么久一定和他有关了 可是并没有使用优先队列 思路: 对于这道题,我们肯定是对他们定义优先级,然 ...

  5. Docker(六)容器数据卷

    容器数据卷 docker的理念回顾 将应用和环境打包成一个镜像 需求:数据可以持久化和同步 使用数据卷 指定路径挂载 docker run -it -v 主机目录:容器内目录 # 测试 [root@h ...

  6. eIQ WSL下工具及环境配置

    1. 配置WSL 参考[https://www.cnblogs.com/hayley111/p/12844337.html] 2. 配置VScode 参考[https://zhuanlan.zhihu ...

  7. gitlab在k8s上运行的一些优化

    由 林坤创建,最终由 林坤修改于七月02,2020 gitlab组件图 gitlab在k8s上占用资源 kubectl top pods -n default | grep git* gitlab-g ...

  8. 「MoreThanJava」Day2:变量、数据类型和运算符

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  9. HDU 3686 Traffic Real Time Query System (图论)

    HDU 3686 Traffic Real Time Query System 题目大意 给一个N个点M条边的无向图,然后有Q个询问X,Y,问第X边到第Y边必需要经过的点有多少个. solution ...

  10. KMP入门

    First.先上一份最原始的无任何优化的代码(暴力): #include <iostream> #include <cstring> using namespace std; ...