66从零开始学Java之集合中的Collection体系

news/2024/4/25 18:47:03

作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦

千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者

前言

截止到今天,我们《从零开始学Java系列》的文章已经要到一个新的阶段了。在此之前,我们学习了Java里的各种基础知识,包括环境配置、基本语法、分支循环、数组、常用类等。而从今天开始,壹哥要给大家介绍另一个我们开发时特别常用的知识点--集合!

其实我们之前学习的数组也是集合的一种,但数组的结构比较简单,并且自身也存在一些天生的缺陷,比如数组的长度是不可修改的。然而在很多情况下,我们在开发时并不能直接确定数据的数量,这就导致我们在开发时不能频繁地使用数组。所以就需要有一种新的存储数据的结构出现,这就是集合类存在的意义。接下来我们就先从整体上来了解一下集合是怎么回事,希望大家能够通过最近的几篇文章,熟练掌握集合的使用和原理。

-----------------------------------------------前戏已做完,精彩即开始---------------------------------------------

全文大约【4400】字,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有丰富的案例及配图视频,让你更好地理解和运用文中的技术概念,并可以给你带来具有足够启迪的思考......

配套开源项目资料

Github:

GitHub - SunLtd/LearnJava

Gitee:

一一哥/从零开始学Java

一. 集合简介

1. 数组缺陷

只要是内部能够持有若干个其他Java对象,并对外提供了访问接口的Java对象,都属于集合。根据之前我们对数组的认知,数组其实也是一种集合,也可以将不同类型的数据存储起来。既然如此,我们为什么还要搞出来一种新的存储结构来进行数据的存储呢?这主要是因为数组自身存在一些缺陷。

我们虽然可以使用数组来保存多个对象,但数组的长度不可变!也就是说,一旦我们在初始化数组时指定了数组的长度,这个数组的长度就不可变了。如果我们要保存数量不断变化的数据,使用数组的效率就会很差。

另外数组也不能保存具有映射关系的数据。有时候我们想根据某个关键字查找到对应的值,数组是做不到的。比如我们想存储学生的成绩信息,”语文—89“,”数学—60“,数组就很难表达出这种一对一的映射关系。

正因如此,数组难以满足我们在开发时的一些需求,所以这就需要有新的存储结构出现,那么集合也就应运而生了。

External Player - 哔哩哔哩嵌入式外链播放器

2. 集合概念

我们可以把集合理解成是一种用于存放对象的容器,可以保存数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组)它就好比是一个锅、一个碗,里面可以存储适当的数据元素,所以集合就是“由若干个确定的数据元素所构成的整体”,负责保存、盛装其他数据,故也被称为容器类。集合的概念在很多编程语言中都有,并不是Java独有的技术。

Java中的集合其实可以理解成是一个”统称“,它实际上主要包括了两种类型的容器,一种是用于存储单个数据元素的Collection集合,属于单列集合,另一种是可以存储键/值对映射关系的Map集合,属于双列集合。这两个集合接口都是集合的根接口,它们各自又包含了一些子接口或实现类。其中Collection集合又包括3种子类型:List、Set和Queue,而Map集合又包括AbstractMap、SortedMap和HashTable等,如下图所示:

Java所有的集合类都位于java.util包下,提供了一个表示和操作对象集合的统一构架,内部包含了大量集合接口,以及这些接口的实现类和操作它们的算法。

  • 接口代表了集合的抽象数据类型,例如Collection、List、Set、Map等。集合中定义多个接口,是为了能够以不同的方式操作集合对象;
  • 实现类代表了集合接口的具体实现,例如ArrayList、LinkedList、HashSet、HashMap等。本质上它们都是可重复使用的数据结构;
  • 算法代表了实现集合接口的对象在执行的一些计算功能,例如搜索和排序等。这些算法都是多态的表现,因为相同的方法可以在相似的接口上有着不同的实现。

另外集合类和数组不一样,数组里的元素既可以是基本类型的值,也可以是对象(实际保存的是对象的引用变量),而集合里只能保存对象(实际上是保存的对象引用变量,但通常习惯上我们认为集合里保存的是对象)。

3. 集合特点

从集合的设计实现来看,Java集合中的接口和实现类进行了分离,比如有序表的接口是List,而具体实现类则是ArrayList、LinkedList等。另外集合还支持泛型,使得一个集合只能存放同一种数据类型的元素。

集合包括List、Set、Map等几种不同的实现形式,从功能上来看,它们也有各自的特点:

  • List集合:List集合是一个有序的、可重复的集合,各个元素对象之间有指定的顺序,且允许出现重复元素和多个值为null的元素对象。
  • Set集合:Set集合是一个不可重复的集合,各个元素对象之间没有指定的顺序,元素不允许出现重复值,且只允许有一个值为null的元素对象。
  • Map集合:Map集合是一个无序的,具有唯一key键,但值不唯一的集合,元素允许出现重复值,且元素可以根据索引进行查找。

4. 集合分类

根据上面的描述和集合架构图,我们知道,Java中的集合其实可以分为两大类,若干子类:

  • Collection:属于单列集合,内部包括List、Set和Queue等子类,其中List是一种有序列表的集合,Set是可以保证没有重复元素的集合。
  • Map:属于双列集合,是可以通过键值(key-value)查找的映射表集合,内部包括AbstractMap、SortedMap和HashTable等子类。

External Player - 哔哩哔哩嵌入式外链播放器

5. 核心接口

在上面的描述中,壹哥给大家说过,组成集合的架构包括了各种接口,这些常用的接口作用如下:

接口名称

作用

Iterator接口

Iterator迭代器是集合类的输出接口,主要用于遍历输出(即迭代访问)Collection集合中的元素。迭代器是集合接口的父接口,子类实现Collection接口时也必须实现Iterator接口。

Collection接口

Collection是List、Set和Queue的父接口,是存放一组单值的最大接口。所谓的单值,是指集合中的每个元素都是一个对象,但我们一般很少直接使用此接口进行直接操作。

Queue接口

Queue是Java提供的实现队列,有点类似于List。

Dueue接口

Dueue是Queue的子接口,是一个双向队列。

List接口

List是最常用的集合接口。List是有序的集合,允许有相同的元素。我们使用List能够精确地控制每个元素插入的位置,用户能够使用索引(即元素在List中的位置,类似于数组下标)来访问List中的元素,这与数组类似。

Set接口

Set中不能包含重复的元素。

Map接口

Map是存放键值对的接口,该接口中的每个元素都是成对出现,以key-value的形式保存。

6. 常用实现类

我们在开发时常用List、Set和Map这3种集合接口,而常用的集合实现类则是ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等。

类名称

作用

ArrayList

ArrayList是基于可变数组实现的List,优点是可以进行快速地随机访问,查询效率高,但数据的增删改操作速度较慢。

LinkedList

LinkedList是基于链表实现的List,对顺序访问进行了优化,数据的增删改操作效率较高,但随机访问的速度相对较慢。

HashSet

HashSet是基于HashMap实现的Set,底层使用HashMap来保存所有的数据元素,内部实现比较简单,优化了査询速度。

TreeSet

TreeSet是一个有序的Set子类,我们可以从中提取一个有序序列。

HashMap

HashMap是根据哈希算法来进行键值对存取的Map集合,属于双列集合。

TreeMap

TreeMap是可以对键对象进行排序的Map集合。

7. 过时API

集合作为Java里特别常用和重要的API,可以说几乎每个Java项目都有集合的身影。但是集合结构从JDK 1.0开始就被设计出来,其设计实现非常久远,中间经历了几次大的修改。这就像一个庞大的机器经历了几十年的修修补补,虽然性能依然强悍,但也存在一些不适合继续使用的过时API,比如:

  • Vector:一种线程安全的List实现类,不推荐使用;
  • Stack:基于Vector实现的LIFO的栈,不推荐使用;
  • Hashtable:一种线程安全的Map实现,不推荐使用;
  • Enumeration<E>:已被Iterator<E>取代,不推荐使用。

以上这些API都已被遗弃,开发时请大家尽量不要再使用。另外现在我们只是简单地认识一下集合中的接口和个别实现类,后面壹哥再详细地给大家进行进行介绍,先不要着急哦。

二. Collection接口

在上面的内容中,壹哥说过,集合主要有两大接口,即Collection和Map,而Collection接口其实又是List和Set的父接口。在开始详细学习List和Set集合类之前,我们先来搞清楚Collection是怎么回事。

1. 简介

Collection接口是List、Set和Queue的父接口,在开发时我们不会直接使用该接口,而是会使用该接口的某个具体实现子类。Collection接口里定义了List/Set/Queue的一些通用方法,这些方法可以操作List、Set和Queue集合,实现对集合基本的添加、删除、判断等操作。

2. 方法

下面是Collection接口中定义的一些常用方法,我们可以先来了解一下这些常用方法的含义,以后开发时这些方法都很常用。

方法名称

说明

boolean add(E e)

向集合中添加一个元素,添加成功后返回true,E是指数据元素的数据类型。

boolean addAll(Collection c)

向集合中添加另一个集合c的所有元素,添加成功后返回true。

void clear()

清除集合中的所有元素,将集合长度变为0。

boolean contains(Object o)

判断集合是否存在指定的元素。

boolean containsAll(Collection c)

判断一个集合是否包含另一个集合c的所有元素。

boolean isEmpty()

判断集合是否为空。

Iterator<E> iterator()

返回一个Iterator对象,用于遍历集合中的元素。

boolean remove(Object o)

从集合中删除一个指定的元素,当集合中包含一个或多个元素o时,

该方法只会删除第一个符合条件的元素,删除成功后返回true。

boolean removeAll(Collection c)

从集合中删除所有在集合c中出现的元素,删除成功后返回true。

boolean retainAll(Collection c)

从集合中删除所有不在集合c里的元素,删除成功后返回true。

int size()

返回集合的元素个数。

Object[] toArray()

将集合转换成一个数组,所有的集合元素会变成对应的数组元素。

因为Collection是一个接口,所以我们不能对其直接进行实例化操作,上述表格中的这些方法,我们需要先创建出某个具体的实现类对象进行调用,比如调用ArrayList对象的相关方法。

External Player - 哔哩哔哩嵌入式外链播放器

三. Iterator迭代器

1. 简介

我们可以使用Iterator迭代器对集合进行遍历,Iterator迭代器是集合类的输出接口,主要用于进行遍历输出(即迭代访问)Collection集合中的每个元素。迭代器是集合接口的父接口,子类实现Collection接口时也必须实现Iterator接口。不同的List对象调用iterator()方法时,会返回不同实现的Iterator对象,该Iterator对象对集合总是具有最高的访问效率。

2. 迭代原理

所谓的迭代,其实是一个重复反馈过程的活动,也就是一遍又一遍地执行相似的任务,其目的通常是为了逼近所需的目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果又会作为下一次迭代的初始值。迭代器的工作原理如下图所示:

3. 基本使用

Iterator迭代器的使用其实也很简单,主要是有两个常用方法,如下所示:

  • boolean hasNext():该方法用于判断集合中是否还有下一个元素;
  • E next():该方法用于返回集合的下一个元素。
import java.util.Iterator;
import java.util.List;public class Demo02 {public static void main(String[] args) {//List遍历方式一,普通for循环:List<String> list = List.of("java", "大数据", "壹壹哥");for(int i=0;i<list.size();i++) {System.out.println("遍历方式一,值="+list.get(i));}//List遍历方式二,迭代器:Iterator<String> it = list.iterator();while(it.hasNext()){//取出下一个值String value = it.next();System.out.println("遍历方式二,值="+value);}//List遍历方式三,增强for循环:内部会自动使用Iteratorfor(String item:list) {System.out.println("遍历方式三,item="+item);}}
}

4. 潜在问题

我们在使用迭代器时,有可能会出现如下若干问题需要我们注意:

  • 迭代器迭代完成后,迭代器的位置在最后一位,所以迭代器只能迭代一次;
  • 迭代器在迭代时,不要多次调用next()方法,否则可能会出现NoSuchElementException异常;
  • 迭代器在迭代时,不能向集合中添加或删除元素,否则会出现ConcurrentModificationException异常。

-----------------------------------------------​​​​​​​正片已结束,来根事后烟---------------------------------------------

四. 结语

至此,壹哥就把集合的基本情况给大家介绍完了,请大家梳理记忆集合类之间的这些关系。我们在面试时,经常会有面试官问我们Java中有哪些集合类,它们是什么关系和区别,其实考察的就是今天的内容。那么今天的重点内容,壹哥给大家总结如下:

  • Java集合类定义在java.util包中;
  • Java集合的接口和实现类进行了分离,支持泛型;
  • Java集合分为Collection和Map两大类,具体又分为List、Set、Queue和Map等子类;
  • Java集合使用Iterator遍历集合,我们在开发时尽量不要使用遗留接口。

另外如果你独自学习觉得有很多困难,可以加入壹哥的学习互助群,大家一起交流学习。


https://www.xjx100.cn/news/3091544.html

相关文章

适合学校或高校老师、学生学习用的网盘推荐

现代教育中&#xff0c;数字化的教学资源和家长的参与度越来越重要。然而文件传输的问题一直是学校和家长面临的一个挑战&#xff0c;网络限制、U盘病毒和文件管理不便等问题&#xff0c;都对教学质量和家校沟通造成了影响。Zoho WorkDrive企业网盘为学校还有教辅机构提供了一个…

Springcloud可视化物联网智慧工地云SaaS平台源码 支持二开和私有化部署

智慧工地平台围绕建筑施工人、物、事的安全管理为核心&#xff0c;对应研发了劳务实名制、视频监控、扬尘监测、起重机械安全监测、安全帽监测等功能一体化管理的解决方案。 智慧工地是聚焦工程施工现场&#xff0c;紧紧围绕人、机、料、法、环等关键要素&#xff0c;综合运用物…

Python3.11+Pyside6开发电影下载程序

VideoSave是一款使用Python3.11Pyside6编写的提供下载电影/电视剧的软件&#xff0c;支持注册、登录、搜索、下载、查看日志等功能&#xff0c;提供了Window、Mac系统安装包。 先上效果图 提供功能 节省寻找资源的时间 ⌚️模糊搜索指定影片 &#x1f434;查看影片下载日志 &…

在vue-cli中快速使用webpack-bundle-analyzer

webpack-bundle-analyzer 是一个可视化资源分析工具&#xff0c;可以直观地分析打包出的文件有哪些&#xff0c;及它们的大小、占比情况、各文件 Gzip压缩后的大小、模块包含关系、依赖项等。 从vue-cli官方的更新记录可以看到&#xff0c;从vue-cli3开始集成report命令 当前环…

在ITSM中,实施变更管理的重要因素!

在ITSM管理中&#xff0c;变更管理是不可或缺的一步。在当今快速变革的商业环境中&#xff0c;组织需要不断地进行变更以适应市场的需求和竞争的压力。 然而&#xff0c;引入变更并成功地实施变更并不容易。变更管理是一种系统化和结构化的方法&#xff0c;旨在确保变更顺利进…

解决requests库中UnicodeError异常的问题

目录 一、问题原因 1、服务器响应包含无法解码的字符 2、编码不一致 二、解决方案 1、捕获异常并处理 2、使用更强大的HTTP库——http.client 3、使用第三方库chardet进行智能编码猜测 三、注意事项 总结 在Python的requests库中&#xff0c;UnicodeError异常通常会在…

只有cpu的时候加载模型

只有cpu的时候加载模型 checkpoint torch.load(model_path, map_locationtorch.device(‘cpu’))

Dubbo开发系列

一、概述 以上是 Dubbo 的工作原理图&#xff0c;从抽象架构上分为两层&#xff1a;服务治理抽象控制面 和 Dubbo 数据面 。 服务治理控制面。服务治理控制面不是特指如注册中心类的单个具体组件&#xff0c;而是对 Dubbo 治理体系的抽象表达。控制面包含协调服务发现的注册中…