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. Javascript数组迭代精髓,拿去花

    数组迭代 数组迭代是处理各数组的利器,编写代码时常常会用到,为我们提供了大大的便利.如果还不知道,真的别告诉别人你知道js哈哈. 以下迭代方法均不会改变原数组,带*为必选对象. 1.arr.forEa ...

  2. Redis自带压测工具(redis-benchmark.exe)

    redis做压测: 可以用自带的redis-benchmark工具,使用简单 压测命令:redis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 10000 压测需要 ...

  3. SQLSTATE[42000]: Syntax error or access violation: 1253 COLLATION 'utf8mb4_unicode_ci' is not valid for CHARACTER SET 'binary'

    SQLSTATE[42000]: Syntax error or access violation: 1253 COLLATION 'utf8mb4_unicode_ci' is not valid ...

  4. Ubuntu图形界面root登录出现“sorry, that didn't work please try again”

    ssh登录主机执行下vim /etc/pam.d/gdm-autologin 注释行 "auth requied pam_succeed_if.so user != root quiet s ...

  5. JQ三种提示框:提示信息框、确认框、输入文本框

    浏览器的三种提示框: alert()提示信息框 confirm()提示确认框 prompt()提示输入文本框 1.alert()提示信息框 效果: 实现代码: <script> alert ...

  6. 深入理解letter-spacing,word-spacing的对比区别

    letter-spacing lletter-spacing 属性增加或减少字符间的空白(字符间距). 该属性定义了在文本字符框之间插入多少空间.由于字符字形通常比其字符框要窄,指定长度值时,会调整字 ...

  7. Synchronized锁的是什么?

    Synchronized锁的是什么? 临界区与锁 并发编程中不可避免的会出现多个线程共享同一个资源的情况,为了防止出现数据不一致情况的发生,人们引入了临界区的概念.临界区是一个用来访问共享资源的代码块 ...

  8. 「杂烩」精灵魔法(P1908逆序对弱化版)

    「杂烩」精灵魔法(P1908逆序对弱化版) 题面: 题目描述 \(Tristan\)解决了英灵殿的守卫安排后,便到达了静谧的精灵领地--\(Alfheim\) .由于$ Midgard$ 处在$ Al ...

  9. python 并发专题(四):yield以及 yield from

    一.yield python中yield的用法很像return,都是提供一个返回值,但是yield和return的最大区别在于,return一旦返回,则代码段执行结束,但是yield在返回值以后,会交 ...

  10. 04 drf源码剖析之版本

    04 drf源码剖析之版本 目录 04 drf源码剖析之版本 1. 版本简述 2. 版本使用 3.源码剖析 4. 总结 1. 版本简述 API版本控制使您可以更改不同客户端之间的行为.REST框架提供 ...