前言

  Java的基础集合框架的内容并不复杂,List、Map、Set 中大概10个常见的集合类,建议多看几遍源码(Java8),然后回过头再来看看这些各路博客总结的知识点,会有一种豁然开朗的感觉。

本文的结构:

一、Java的基础集合

  Java的集合主要有 Set、List、Queue、Map 等。其中,Set、List、Queue 继承于 Collection,而 Map 的实现用于保存具有映射关系的数据(key-value),和 Collection 有一定的差别,它是另一个上层接口。继承结构如下:

Collection:

Map:

二、基本特征:

  • List:有序集合(读取数据和存放数据的顺序一致),元素可以重复,访问元素可以根据元素的索引来访问。
  • Set:无序集合(读取数据和存放数据的顺序不一致),类似于数学上的集合概念,根据元素本身来访问元素和进行重复性判断,因此元素不可以重复。
  • Map:保存 Key-value 对形式的元素,访问时只能根据每项元素的 key 来访问其 value。
  • Set 和 Map 容器都有基于哈希存储和排序树(红黑树)的两种实现版本,基于哈希存储的版本理论存取时间复杂度为 O(1)(没有哈希冲突),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果,各类操作的时间复杂度为 O(logN)。

三、集合的几种实现:

  • 数组:数组占用连续内存空间,根据索引查找(即读取)或修改指定索引的元素,速度较快,但是指定索引处的增删慢。
  • 列表:一般通过数组实现,但可以自动扩展,通过将旧元素复制到新的内存空间上进行扩容。
  • 链表:改快读慢;充分利用了内存,存储空间是不连续的,首尾存储上下一个节点的信息,所以寻址麻烦,查找速度慢,但是找到元素后增删快。
  • 哈希表:链表哈希表综合了前两者的优点,一个哈希表,由数组和链表组成。

四、集合常见的实现类:

1、List的常见实现类

  1. ArrayList:数组实现,查询快,指定索引处增删慢(需要移动后续的元素);对插入的元素不进行判断,元素可为空,也可以重复,元素读取和存放同序;轻量级、线程不安全,可以用 Collections 配合 ArrayList 实现线程同步;
  2. LinkedList:链表实现,增删快(前提是要找到指定的结点),查询慢
  3. Vector:数组实现,查询快,增删慢,线程安全,重量级

2、Map的常见实现类

  1. HashMap:键值对,key 不能重复(相同的 key,其旧的 value 会被覆盖),但是 value 可以重复;整体实现是数组+链表(红黑树);允许 null 的键或值;线程不安全,可配合 Collections 工具类使用实现线程安全,或者使用 ConcurrentHashMap。
  2. Hashtable(弃用):线程安全的,其线程安全是通过 Sychronize 实现,不允许 null 的键或值;
  3. Properties::key 和 value 都是 String 类型,用来读配置文件;
  4. TreeMap:对 key 排好序的 Map;key 要实现 Comparable 接口或 TreeMap 的构造器中传入 Comparator;内部以 red-black(红-黑)树数据结构实现,插入,删除和查找的时间复杂度都是 O(log n);实现了SortedMap接口。
  5. LinkedHashMap:是 HashMap 的子类,对 HashMap 进行了扩展,其与 HashMap 的不同之处在于,它维护着一个运行于所有条目的双重链接列表。存储的数据是有序的。保存了记录(或访问)的插入顺序

注:ConcurrentHashMap:线程安全,是通过 Lock 的方式实现的,并且锁分离。ConcurrentHashMap 内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的 hasMap,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。

3、Set的常见实现类

  1. HashSet:存放重复的元素时,只会保留一个。一般需要重写 hashCode() 方法,采用恰当的方式分配散列码。内部实现是 HashMap,元素为 key,value 是同个 Object 对象。
  2. TreeSet:SortedSet 的实现类,实现排序,因此添加到 TreeSet 的元素必须是可排序的(元素自身可排序或者提供 Comparator 进行排序),它总是平衡的,保证了插入、删除、查询的性能为 log(n)。内部实现是 TreeMap。
  3. HashSet 和 TreeSet 都实现了 Cloneable 接口
  4. HashSet 的后台有一个 HashMap;初始化后台容量;只不过生成一个 HashSet 的话,系统只提供 key 的访问;如果有两个 Key 重复,那么会覆盖之前的;equals 返回 true,hashCode 返回相同的整数;哈希表;存储的数据是无序的。
  5. LinkedHashSet:与 HashSet 的不同之外在于,维护着一个运行于所有元素的双向链接。存储的数据是有序的。内部实现是 LinkedHashMap

五、集合常见实现类的源码解析

List

  1. ArrayList 实现原理:参考我的博客:Java8集合框架——ArrayList
  2. LinkedList 实现原理:参考我的博客:Java8集合框架——LinkedList
  3. Vector 实现原理:其实现和 ArrayList 类似,因方法中使用了 synchronized 进行同步,是线程安全的

Map

  1. HashMap 和ConcurrentHashMap 实现原理:参考别人的博客:Java7/8中的 HashMap 和 ConcurrentHashMap 全解析
  2. LinkedHashMap 实现原理:扩展自 HashMap,加了自己的一些扩展功能,以支持双向链表。待补充。。。。

Set

  1. HashSet 实现原理:其底层使用 HashMap,元素为 key,而value是同一个 Object,即 private static final Object PRESENT = new Object(); 原理类似。
  2. LinkedHashSet 实现原理:扩展自 HashSet,但是其底层使用 LinkedHashMap,元素为 key,而value是同一个 Object,即 private static final Object PRESENT = new Object(); 原理和 LinkedHashMap 类似。
  3. TreeSet 实现原理:底层是使用 TreeMap。

六、Collection、Collections、Arrays的区别

  1. Collection:集合类的上级接口,继承于他的接口主要有 Set、List。Set 里的元素是不能重复的,equals() 方法来区分重复与否。
  2. Collections:是针对集合类的一个工具类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
  3. Arrays:此类包含用来操作数组(比如排序和搜索)的各种方法。

七、其他待补充

以下这几点的内容待研究和补充。。。。

1、集合迭代Iterator

2、Iterator的fail-fast和fail-safe

  1. 每次我们尝试获取下一个元素的时候,Iteratorfail-fast 属性检查当前集合结构里的任何改动(使用内部属性 modCount,修改计数器)。如果发现任何改动,它抛出 ConcurrentModificationExceptionCollection 中所有 Iterator 的实现都是按fail-fast 来设计的(ConcurrentHashMapCopyOnWriteArrayList 这类并发集合类除外)。
  2. Iteratorfail-fast 属性与当前的集合共同起作用,因此它不会受到集合中任何改动的影响。java.util 包中的所有集合类都被设计为 fail-fast 的,而 java.util.concurrent 中的集合类都为 fail-safe 的。fail-fast 迭代器抛出 ConcurrentModificationException,而 fail-safe 迭代器从不抛出 ConcurrentModificationException
  3. 在 Java fail fast 迭代器中,迭代 objects 集合有时会出现并发修改异常,出现这种情况有2个原因:①如果一个线程正在迭代一个集合,而另一个线程同时试图修改这个集合;②遍历过程中,试图去修改集合。注:在遍历过程中调用 remove() 方法不会引起 ConcurrentModificationException
  4. fail-fast(快速失败):快速失败机制在遍历一个集合时,如果集合内容被修改,会抛出 ConcurrentModificationException 异常。
  5. fail-safe(安全失败):安全失败机制对集合的任何修改都会在一个复制的集合上进行,因此不会抛出异常。

Java8集合框架——基本知识点的更多相关文章

  1. Java8集合框架——LinkedList源码分析

    java.util.LinkedList 本文的主要目录结构: 一.LinkedList的特点及与ArrayList的比较 二.LinkedList的内部实现 三.LinkedList添加元素 四.L ...

  2. Java8集合框架——ArrayList源码分析

    java.util.ArrayList 以下为主要介绍要点,从 Java 8 出发: 一.ArrayList的特点概述 二.ArrayList的内部实现:从内部属性和构造函数说起 三.ArrayLis ...

  3. Java8集合框架——LinkedHashMap源码分析

    本文的结构如下: 一.LinkedHashMap 的 Javadoc 文档注释和简要说明 二.LinkedHashMap 的内部实现:一些扩展属性和构造函数 三.LinkedHashMap 的 put ...

  4. Java8集合框架——集合工具类Arrays内部方法浅析

    java.util.Arrays 备注:本文只对 Java8 中的 java.util.Arrays 中提供的基本功能进行大致介绍,并没有对其具体的实现原理进行深入的探讨和分析.详情可自己深入观摩源码 ...

  5. Java8集合框架——HashMap源码分析

    java.util.HashMap 本文目录: 一.HashMap 的特点概述和说明 二.HashMap 的内部实现:从内部属性和构造函数说起 三.HashMap 的 put 操作 四.HashMap ...

  6. Java8集合框架——LinkedHashSet源码分析

    本文的目录结构如下: 一.LinkedHashSet 的 Javadoc 文档注释和简要说明 二.LinkedHashSet 的内部实现:构造函数 三.LinkedHashSet 的 add 操作和 ...

  7. Java8集合框架——HashSet源码分析

    本文的目录结构: 一.HashSet 的 Javadoc 文档注释和简要说明 二.HashSet 的内部实现:内部属性和构造函数 三.HashSet 的 add 操作和扩容 四.HashSet 的 r ...

  8. Lambda表达式和Java集合框架

    本文github地址 前言 我们先从最熟悉的Java集合框架(Java Collections Framework, JCF)开始说起. 为引入Lambda表达式,Java8新增了java.util. ...

  9. Java最重要的21个技术点和知识点之JAVA集合框架、异常类、IO

    (三)Java最重要的21个技术点和知识点之JAVA集合框架.异常类.IO  写这篇文章的目的是想总结一下自己这么多年JAVA培训的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享 ...

随机推荐

  1. 微信小程序IOS真机调试发生了SSL 错误,无法建立与该服务器的安全连接

    小程序 真机调试 IOS request:fail 发生了SSL 错误,无法建立与该服务器的安全连接,解决方法服务器中打开Powerhell,执行以下代码,然后重启服务器 # Enables TLS ...

  2. html的适配

    html值得一说的应该就是适配 !!适配是与手机同时存在的 写好一个页面在手机端打开,会发现这个页面显示很小,那是因为设备的视口宽度viewport不等于设备宽度device-width,而页面是根据 ...

  3. Day5 - F - 食物链 POJ - 1182

    动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A.现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种.有人用两种说法 ...

  4. Educational Codeforces Round 64 选做

    感觉这场比赛题目质量挺高(A 全场最佳),难度也不小.虽然 unr 后就懒得打了. A. Inscribed Figures 题意 给你若干个图形,每个图形为三角形.圆形或正方形,第 \(i\) 个图 ...

  5. Django(十)模型:django模型类对数据库的:增/删/改/查、自关联、管理器、元选项(指定表名)

    一.插入.更新和删除 调用一个模型类对象的save方法的时候就可以实现对模型类对应数据表的插入和更新. 调用一个模型类对象的delete方法的时候就可以实现对模型类对应数据表数据的删除. 二.自关联 ...

  6. C++输入问题探究

    突发奇想对C++输入输出做一点研究,主要是做笔试题自己写输入老是花很多时间,所以做一个总结. 对于输入多行字符串,代码如下: #include<iostream> #include< ...

  7. 2.10 学习总结 之 JQ加强

    一.说在前面  昨天 完成了体温统计APP的编写 今天 学习json数据结构 二.学习总结 1.json数据结构 1)什么是json: JSON(JavaScript Object Notation) ...

  8. R apply()函数

    创建一个列表变量,它的第一个元素包含所有从0到9的平方数,第二个元素为10到19之内的所有平方数,依此类推,最后一个元素为90到99之内的平方数.没有平方数的元素也应该被包含在内! 学习网友的解题思路 ...

  9. Ajax学习系列——向服务器发送请求

    1.如何发送请求? 如果需要向服务器发送请求,我们使用的是XMLHttpRequest对象中的open()和send()方法. var xhr = new XMLHttpRequest();//具体创 ...

  10. 如何通过 Python 和 OpenCV 实现目标数量监控?

    今天我们将利用python+OpenCV实现对视频中物体数量的监控,达到视频监控的效果,比如洗煤厂的监控水龙头的水柱颜色,当水柱为黑色的超过了一半,那么将说明过滤网发生了故障.当然不仅如此,我们看的是 ...