【JavaSE】Java 容器---集合

集合框架的概述

集合、数组都是对多个数据进行存储操作的结构,简称 Java 容器

说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储

数组在存储多个数据方面的特点:

  • 一旦初始化,其长度就确定了
  • 数组一旦定义好,其元素的类型也就确定了,就只能操作指定类型的数据了

数组在存储多个数据方面的缺点:

  • 一旦初始化,其长度就确定了
  • 数组中提供的方法非常有限,对于添加,删除,插入数据等操作,非常不便,同时效率不高
  • 获取数组中实际元素的个数的需求,数组没有现成的属性和方法可用
  • 数组存储数组的特点:有序,可重复,对于无序,不可重复的需求,不能满足

在java中的可分为Collection 和 Map 两种体系

Collection 接口:单列数据,定义了存取一组对象的方法的集合

  • List : 元素有序,可重复的集合
  • Set: 元素无序,不可重复的集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Ml9Ky3N-1664415148716)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-16 211026.png)]

Map 接口 :双列数据,保存具有映射关系的 " key - value 对"的集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TYvGfMyy-1664415148718)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-16 211112.png)]

Collection 接口

Collection 接口的概述

Collection 接口是List、Set 和Queue 接口的父接口,该接口里定义的方法既可用于操作Set 集合,也可用于操作List 和Queue 集合。

JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List)实现。

在Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成Object 类型处理;从JDK 5.0 增加了泛型以后,Java 集合可以记住容器中对象的数据类型

Collection 接口中的常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-68Lyvjt2-1664415148719)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-16 211310.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pwIiaQTd-1664415148720)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-16 211322.png)]

向Collection 接口中的实现类的对象中添加数据obj时,要求obj所在类要重写equals() 方法

使用Iterator 迭代器接口

Iterator 对象称为迭代器(设计模式的一种),主要用来遍历Collection 集合中的元素

GOF 个迭代器模式的定义:提供一种方法访问一个容器 (Container) 对象中的各个元素,而又不能暴露该对象的内部细节,迭代器模式,就是为容器而生。

Collection 接口继承了 lterable 接口,该接口中有一个 iterator 方法,那么所有实现了 Collection 接口的集合类都有一个 iterator() 方法,用于返回一个实现了 lterable 接口的对象

Iterator 只用于遍历集合,Iterator 本身并不提供承装对象的能力,如果需要创建 Iterator 对象,则必须有一个迭代器的集合

集合对象每次调用 iterator() 方法得到的一个全新的迭代器对象,默认游标都在集合的第一个元素之前

Iterator 接口中的常用方法

返回值方法描述
booleanhasNext()如果迭代有更多元素,返回true
Enext()返回迭代的下一个元素
default voidremove从底层集合中删除此迭代器中返回的最后一个元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdzP5KOw-1664415148721)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-17 090325.png)]

注意

  • Iterator 可以删除集合的元素,但是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法
  • 如果还未调用 next() 或在上一次调用 next 方法 之后 已经调用了remove 方法,在调用remove 都会报 IllegalStateException 的异常

foreach 循环 (加强for循环)

在java5.0 提供了 foreach 循环迭代访问 Collection 和数组

遍历操作不需要获取 Collection 或数组的长度,无需使用 索引 访问元素

遍历集合的底层使用 Iterator 完成操作

foreach 也可用于遍历数组

//for(要遍历的类型 遍历后自定义的元素名称:要遍历的结构名称){ }
int[] arr = new int(){ 1,2,3 };
for(int i:arr){
    System.out.println(i)
}

List 接口

List 接口的概述

List 接口是 Collection 接口的子接口之一

在 List 集合类中元素有序,可重复,集合中的每个元素都有其对应的顺序索引

List 容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素

JDK API 中List 接口中的实现类常用的有:ArrayList,LinkedList 和 Vector

List 接口中 的 ArrayList,LinkedList 和 Vector 三个实现类的异同

同:三者都是 List 接口下的三个实现类,它们对象可存储的元素都是 有序的,可重复的

异:

  • ArrayList : 作为List 接口中的主要实现类;线程是不安全的,效率高;底层使用 Object[] elementData 存储
  • LinkedList : 对于频繁的插入,删除操作,使用此类效率比 ArrayList 高;底层使用双向链表存储
  • Vector: 作为List 接口的古老实现类;线程是安全的, 效率低;底层使用Object[] elementData 存储

List 接口中的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X1zXwyg5-1664415148721)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-17 103456.png)]

List 实现类之一:ArrayList 类

ArrayList 是 List 接口中的典型实现类,主要实现类

本质上,ArrayList 是对象引用的一个 “变长” 的数组

对ArrayList类的源码分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0svclyPi-1664415148722)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-17 112051.png)]

ArrayList 总结 : 如果是在 jdk7 的版本中,直接使用 new 的方式创建一个 ArrayList 的对象,没有指明指定的集合的元素存储数据的长度,就会默认创建一个长度为 10 的数组,如果添加到超出集合长度,底层的 elementData 数组容量不够,则会会进行扩容,在默认情况下,扩容的为原来的容量的 1.5 倍,同时需要将原有的数组中的数据复制到新的数组中

在 jdk8 及后来的版本中,直接使用new 的方式创建一个 ArrayList 的对象并没有指定集合元素的长度,底层并不会创建为 10 的数组,而在使用 add() 方法向数组中添加元素时,底层就会默认创建一个 长度为 10 的数组,并将 add() 中要添加的数据添加到 elementData[0] 中。如果添加超出数组的长度,底层的 elementData 数组容量不够,则会继续进行扩容,在默认情况下,扩容的长度为原数组容量的 1.5 倍,同时将原有的数组中的元素复制到新的数组中

List 实现类之一:LinkedList 类

如果频繁的插入或删除元素的操作,建议使用LinkedList 类,效率较高

LinkedList : 双向链表,内部没有声明数组,而是定义了Node 类型的 first 和 last 用于记录首末元素,同时定义内部类Node,作为LinkedList 中保存数据的基本结构。Node除了保存数据

还定义了两个变量:

  • prev 变量记录前一个元素的位置
  • next 变量记录下一个元素的位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i3UF8uXW-1664415148723)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-17 160213.png)]

LinkedList 简视图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hozi38yx-1664415148723)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-19 094202.png)]

新增方法 :

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ile5miw-1664415148724)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-20 081613.png)]

List 实现类之一 : Vector 类

  • Vector 是一个古老的实现类,jdk1.0就有了。大多数操作与ArrayList相同,区别之处在于 Vector 是线程安全的
  • 在各种 list 中,最好把 ArrayList 作为缺省选择。当插入,删除频繁时使用 LinkedList; Vector 总是比 ArrayList 慢,所以尽量避免使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-03Q0elDW-1664415148724)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-20 081040.png)]

Set接口

Set 接口的概述

  • Set 接口时 Collection 的子接口,Set 接口没有提供额外的方法

  • Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法

  • Set 集合不允许包含相同的元素,如果似把两个相同的元素加入同一个Set集合中,则添加失败

Set: 存储的是无序的,不可重复的数据 (以 HashSet 为例说明)

  1. 无序性:不等于随机性,存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的
  2. 不可重复性:保证添加的元素按照 equals() 方法判断时,不能返回true,即相同的元素只能添加一个

添加元素的过程 ( 以HashSet为例 )

我们向 HashSet 中添加元素a,首先调用元素 a 所在类的 hashCode() 方法,计算元素 a 的哈希值,此哈希值接着通过某种算法计算出在 HashSet 底层数组中的存放位置 (即为索引数据),判断数组此位置上是否已经有元素 :

  • 如果此位置上没有其他元素,则元素a 添加成功
  • 如果此位置上有其他元素 b (或以链表形式存在的多个元素),则比较元素a 与 元素 b 的 哈希值。如果哈希值不相同,则元素添加成功,如果哈希值相同,需要调用元素 a 所在类中的 equals() 方法,如果equals() 方法返回的是 true,添加失败,如equals() 方法返回的是false,添加成功
  • 在 jdk7 : 元素 a 放到 数组中,指向的是原来的数据,而在 jdk8 : 原来的元素在数组中,指向元素 a

Set 实现类之一 : HashSet集合

  • HashSet 是接口 Set 接口的典型实现,大多数时候使用 Set 集合时都是用这个实现类
  • HashSet 按Hash 算法来存储集合中的元素,因此具有很好的存取,查找,删除性能
  • HashSet 具有以下的性能

​ >不能保证元素的排序顺序

​ >HashSet 不是线程安全的

​ >集合元素可以是 null

  • HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法放回值也相等

  • 对于存放在 Set 容器中的对象,对应的类一定要重写 equals() 和 hashCode(Object obj) 方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”

    向HashSet 添加元素的过程:

>向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据hashCode值,通过某种散列函数决定该对象在HashSet底层数组中的存储位置。(这个散列函数会与底层数组的长度相计算得到在数组中的下标,并且这种散列函数计算还尽可能保证能均匀存储元素,越是散列分布,该散列函数设计的越好)

>如果两个元素的hashCode()值相等,会再继续调用equals方法,如果equals方法结果为true,添加失败;如果为false,那么会保存该元素,但是该数组的位置已经有元素了,那么会通过链表的方式继续链接。

  • 如果两个元素的 equals() 方法返回 true,当他们的 hashCode() 返回值不相等,HashSet将会把它们存储在不同的位置,但依然可以添加成功。

  • HashSet 集合保存数据的简视图:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NbIM0K0C-1664415148725)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-17 164523.png)]

Set 实现类之二 : LinkedHashSet集合

  • LinkedHashSet 是 HashSet 的子类

  • LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入的顺序保存的

  • LinkedHashSet 插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能

  • LinkedHashSet 不允许集合元素重复

  • LinkedHashSet 存储数据简视图:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j6VGfIwT-1664415148726)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-17 165319.png)]

Set 实现类之三 : TreeSet集合

  • 向TreeSet 中添加数据,要求是相同类的对象
  • TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保元素处于排序状态
  • TreeSet 两种排序方法 :自然排序和定制排序。默认情况下,使用的是自然排序

重写 equals() 和 hashCode() 方法的标准

一、重写 hashCode() 方法的基本原则

  • 在程序运行时,同一个对象多次调用 hashCode() 方法返回相同的值
  • 当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等
  • 对象中用在 equals() 方法比较的 Field(属性),都应该用来计算 hashCode 值

二、重写 equals() 方法的基本原则

  • 当一个类有自己特有的 “逻辑相等” 概念,当改写 equals() 的时候,总是要改写 hashCode(),根据一个类的 equals 方法,两个截然不同的实例有可能在逻辑上是相等的,但是根据 Object.hashCode() 方法,它们只是两个对象
  • 因此,违法了 “相等的对象必须具有相等的散列码”
  • 结论:复写 equals 方法的时候一般都需要同时 复写 hashCode 方法,通过常参与计算hashCode的对象的属性也应该参与到 equals() 中进行计算

Map接口

Map 接口的概述

  • Map 与 Collection 并列存在,用于保存具有映射关系的数据: key - value
  • Map 中的 key 和 value 都可以是任何引用数据类型
  • Map 中的 key 用 Set 来存放,不允许重复,即同一个Map 对象所对应的类,要重写 hashCode() 和 equals() 方法
  • 常用 String 类作为 Map 的 “键”(key)
  • key 和 value 之间存在单向一对一的关系,即通过指定的key总能找到唯一的,确定的 value
  • Map 接口中的常用类:HashMap,TreeMap,LinkedHashMap和Properties,其中 HashMap 是 Map 接口使用频率最高的实现类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qGVmEHJy-1664415148726)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 160612.png)]

Map 接口中的 key 值不能重复,value 值可以存在重复的

Map 结构的理解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p2pYuPQ4-1664415148727)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 155455.png)]

  • Map 中的 key : 无序的,不可重复的,使用 Set 存储所有的 key —> key 所在的类要重写 equals() 和 hashCode() 方法
  • Map 中的 value : 无序的,可重复的,使用 Collection 存储所有的 value —> value 所在类要重写 equals() 方法
  • 一个键值对 :key - value 构成了一个 Entry 对象
  • Map 中的entry 无序的,不可重复的,使用 Set 存储所有的 entry

Map 接口常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Odrkcly-1664415148728)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 160734.png)]

Map 接口中的底层实现原理 (以HashMap为例)

jdk7.0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V8N4xwUM-1664415148729)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 161633.png)]

jdk8.0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UORKZzy3-1664415148730)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 161954.png)]

Map 实现类之一 : HashMap集合

HashMap 集合概述
  • HashMap 是 Map 接口中使用频率最高的实现类
  • 允许使用 null 键 和 null 值,与HashSet 一样,不保证映射的顺序
  • 所有的 key 构成集合是 Set : 无序的,不可重复的。所以 key 所在的类要重写 : equals() 和 hashCode() 方法
  • 所有的value 构成的集合是 collection : 无序的,可重复的,所有 value 所在的类要重写 : equals() 方法
  • 一个 key - value 构成一个entry
  • 所有的 entry 构成的集合是 Set : 无序的,不可重复的
  • HashMap 判断两个 key 相等的标准是 : 两个 key 通过 equals () 方法返回 true,hashCode 值也相等
  • HashMap 判断两个 value 相等的标准是 : 两个 value 通过 equals () 方法返回 true
HashMap 的存储结构

jdk7 和以前的版本使用的是 :HashMap是数组 + 链表结构

jdk8 版本以后使用的是 :HashMap是数组 + 链表结构 + 红黑树实现

jdk7.0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YPkhEUfS-1664415148730)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 163215.png)]

jdk8.0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rDZsWahg-1664415148731)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 163223.png)]

HashMap 源码中的重要常量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yq5Ak5gs-1664415148731)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 163606.png)]

HashMap 的存储结构
jdk7:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bsdAfMUg-1664415148732)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 173326.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bfAa913Q-1664415148733)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 173337.png)]

jdk8:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FjeYlc1l-1664415148733)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 173345.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CEVjkoU8-1664415148734)(F:\后端学习\java学习笔记\学习图片\屏幕截图 2022-03-18 173353.png)]

Map 实现类之二 : LinkedHashMap集合

  • LinkedHashMap 是 HashMap 的子类
  • 在HashMap 存储结构的继承上,使用了一对双向链表来记录添加元素的顺序
  • 与 LinkedHashSet 类似,LinkedHashMap 可以维护Map的迭代顺序 : 迭代顺序与 Kay - Value 对的顺序一致

Map 实现类之三 : TreeMap集合

  • TreeMap 存储 key - value 对时,需要根据 key - value 对进行排序。TreeMap 可以保证所有的 key - value 对处于有序状态
  • TreeSet 底层使用红黑数结构存储数据
  • TreeSet 的 key 的排序

​ >自然排序:TreeMap 的所有的 key 必须实现 Comparable 接口,而且所有的key 应该是同一个类的对象,否则将会抛出 ClasssCastException

​ >定制排序:创建 TreeMap 时,传入一个Comparator对象,该对象负责对 TreeMap 中的所有key 进行排序,此时不需要 Map 的 key 实现 Comparable 接口

  • TreeMap 判断两个 key 相等的标准 : 两个 key 通过 compareTo() 方法或者 compare () 方法返回 0

Map 实现类 之四 : Hashtable

  • Hashtable 是一个古老的实现类,JDK1.0提供了。不同于 HashMap,Hashtable 是线程安全的
  • Hashtable 实现原理和 HashMap 相同,功能相同。底层都使用哈希表结构,查询速度快,在很多情况下可以互用
  • 与HashMap 不同,Hashtable 不允许使用 null 作为 key 和 value
  • 和 HashMap 一样,Hashtable 不能保证其中的 key - value 对的顺序
  • Hashtable 判断两个 key 相等,两个 value 相等的标准,和 HashMap 一样,使用 hashCode() 和 equals() 方法判断 key 值是否相等

Map 实现类之五 : Properties

  • Properties 类是 Hashtable 的子类,改对象用于处理属性文件
  • 由于属性文件里的 key ,value 都是字符串类型,所以 Properties 里的key 和 value 都是字符串类型
  • 存取数据时,建议使用 setProperty(String key,String value) 方法和 getProperty(String key) 方法

Collections 工具类

Collections 工具类概述

  • Collections 是一个操作 Set,List 和 Map 等集合的工具类

  • Collections 中提供了一系列静态的方法对集合元素进行排序,查询和修改等操作,还提供了对集合对象设置不可变,对集合对象实现同步控制等方法

    Collections 常用方法 (均为静态方法)

    • 排序操作

    reverse(List) : 反转List 中的顺序

    shuffle(List) : 对 List 集合元素进行随机排序

    sort(List) : 根据元素的自然排序对指定 List 集合元素进行升序排序

    sort(List,Comparator) : 根据指定的 Comparator 产生的顺序对 List 集合元素进行排序

    swap(List,int i,int j) : 将指定的 List 集合中的 i 处元素和 j 处元素进行交换

    • 查找,替换

    Object max(Collection) : 根据 元素的自然排序,返回给定集合中的最大元素

    Object max(Collection,Comparator) : 根据 Comparator 指定的顺序,返回给定集合中的最大元素

    Object min(Collection) : 根据元素的自然排序,返回给定集合中的最小元素

    Object min(Collection,Comparator) : 根据 Comparator 指定的顺序,返回给定集合中的最小元素

    int frequency(Collection,Object) : 返回指定集合中指定元素的出现次数

    void copy(List dest,List src) : 将 src 中的内容复制到 dest 中

    boolean replaceAll(List list,Object oldVal,Object newVal) : 使用新增替换 list 对象中所有的旧值

    Collections 常用方法 : 同步控制
    • Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合中的线程安全问题

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

꧁小ۣۖิ鸽ۣۖิ子ۣۖิ꧂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值