集合和泛型的详细讲解

news2024/9/27 21:26:50

集合

1)可以动态保存任意多个对象,使用比较方便!

2)提供了一系列方便的操作对象的方法:add、remove、set、get等3)使用集合添加,删除新元素的示意代码-简洁了
在这里插入图片描述
在这里插入图片描述

集合的框架体系

Collection 接口和常用方法

Collection 接口实现类的特点

1)collection实现子类可以存放多个元素,每个元素可以是Object

2)有些Collection的实现类,可以存放重复的元素,有些不可以

3)有些Collection的实现类,有些是有序的(List),有些不是有序(Set)

4)Collection接口没有直接的实现子类,是通过它的子接口Set和 List来实现的

Collection 接口遍历元素方式 1-使用使用 Iterator(迭代器)

基本介绍

在这里插入图片描述

1 )Iterator对象称为迭代器,主要用于遍历 Collection集合中的元素。2)所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器。

3)Iterator的结构.[看一张图]

4)Iterator 仅用于遍历集合,Iterator本身并不存放对象。

提示:在调用iterator.next()方法之前必须要调用iterator.hasNext()进行检测。若不调用,且下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常。
在这里插入图片描述

在这里插入图片描述

Collection 接口遍历对象方式 2-for

在这里插入图片描述

List 接口和常用方法

List 接口基本介绍

List接口是 Collection接口接口

1)List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复

2)List集合中的每个元素都有其对应的顺序索引,即支持索引。
在这里插入图片描述

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

JDKAPI中List接口的实现类:

List 接口和常用方法

常用的 ArrayList LinkedList和Vector

List 接口的常用方法

  1. boolean addAll(int index, Collection eles):从 index位置开始将 eles 中的所有元素添加
  2. Object get(int index):获取指定 index 位置的元素
  3. int indexOf(Object obj):返回 obj 在集合中首次出现的位置
  4. int lastIndexOf(Object obj):返回 obj 在当前集合中末次出现的位置
  5. Object remove(int index):移除指定 index 位置的元素,并返回此元素
  6. Object set(int index, Object ele):设置指定 index 位置的元素为 ele , 相当于是替换.
  7. List subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 位置的子集合

注意返回的子集合 fromIndex <= subList < toIndex

List 的三种遍历方式 [ArrayList, LinkedList,Vector]

在这里插入图片描述

ArrayList 底层结构和源码分析

ArrayList 的注意事

1) permits all elements, including null , ArrayList 可以加入null,并且多个

2) ArrayList是由数组来实现数据存储的

3) ArrayList 基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码 在多线程情况下,不建议使用ArrayList

ArrayList 的底层操作机制源码分析(重点,难点.)

1)ArrayList中维护了一个Object类型的数组elementData. transient Object[] elementData; //transient表示瞬间,短暂的,表示该属性不会被序列号

2)当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。

3)如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。

示意图:

在这里插入图片描述

Vector 底层结构和源码剖析

Vector 的基本介绍

在这里插入图片描述

//如果 需要的数组大小 不够用,就扩容 , 扩容的算法

//newCapacity = oldCapacity + ((capacityIncrement > 0) ?

// capacityIncrement : oldCapacity);

//就是扩容两倍.

Vector 和 ArrayList的比较

在这里插入图片描述

LinkedList 底层结构

LinkedList 的全面说

1)LinkedList底层实现了双向链表和双端队列特点

2)可以添加任意元素(元素可以重复),包括null

3)线程不安全,没有实现同步

LinkedList底层操作机制

1)LinkedList底层维护了一个双向链表

2)LinkedList中维护了两个属性first和last分别指向首节点和尾节点

3)每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表.

4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。

模拟一个简单的双向链表

在这里插入图片描述

LinkedList 的增删改查案例

  1. linkedList.remove(); // 这里默认删除的是第一个结点
  2. linkedList.set(1, 999); //修改某个结点对象
  3. /get(1) 是得到双向链表的第二个对象Object o = linkedList.get(1)
  4. //因为 LinkedList 是 实现了 List 接口, 遍历方式

System.out.println(“=LinkeList 遍历迭代器==”);

Iterator iterator = linkedList.iterator();

while (iterator.hasNext()) {

Object next = iterator.next();

System.out.println(“next=” + next);

}

ArrayList 和 LinkedList 比较

在这里插入图片描述

Set 接口和常用方法

Set 接口基本介绍

1)无序(添加和取出的顺序不一致),没有索引

2)不允许重复元素,所以最多包含一个null

在这里插入图片描述

3)JDK APl中Set接口的实现类有:

Set 接口的常用方法

和List 接口一样, Set 接口也是 Collection的子接口 因此 常用方法和 Collection 接口一样.

Set 接口的遍历方式

  1. 可以使用迭代器

  2. 增强for

  3. 不能使用索引的方式来获取

Set 接口实现类-HashSet

HashSet 的全面说明

在这里插入图片描述

1)HashSet实现了Set接口

2)HashSet实际上是HashMap,

3)可以存放null值,但是只能有一个null

4)HashSet不保证元素是有序的,取决于hash后,再确定索引的结果.(即,不保证存放元素的顺序和取出顺序一致)

5)不能有重复元素/对象.在前面Set接口使用已经讲过

HashSet 底层机制说明

分析HashSet底层是HashMap, HashMap底层是(数组+链表+红黑树)

>分析HashSet的添加元素底层是如何实现(hash()+equals())

在这里插入图片描述

在这里插入图片描述

分析HashSet的扩容和转成红黑树机制

在这里插入图片描述

Set 接口实现类-LinkedHashSet

LinkedHashSet的全面说明
在这里插入图片描述

1)LinkedHashSet是 HashSet的子类

2)LinkedHashSet底层是一个 LinkedHashMap,底层维护了一个数组+双向链表

3)LinkedHashSet根据元素的 hashCode值来决定元素的存储位置,同时使用链表维护元素的次序(图),这使得元素看起来是以插入顺序保存的。

4)LinkedHashSet不许添重复元素
在这里插入图片描述

Map 接口和常用方法

Map 接口和常用方法

注意:这里讲的是JDK8的Map接口特点

1)Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value2)Map中的key和 value可以是任何引用类型的数据,会封装到HashMap$Node对象中

3)Map中的 key不允许重复,原因和HashSet一样,前面分析过源码

4)Map中的value可以重复

5)Map的key可以为 null, value也可以为null,注意 key 为null只能有一个,value为null,可以多个.

6)常用String类作为Map的 key

7)key和 value之间存在单向一对一关系,即通过指定的key总能找到对应的 value

8)Map存放数据的key-value示意图,一对k-v是放在一个HashMap$Node中的,有因为Node实现了 Entry接口,有些书上也说一对k-v就是一个Entry(如图)

在这里插入图片描述

Map 接口常用方法

remove:根据键删除映射关系

get:根据键获取值

size:获取元素个数

isEmpty:判断个数是否为0

clear:清除 k-v

containsKey:查找键是否存在

Map 接口遍历方法

在这里插入图片描述

  1. containsKey:查找键是否存在
  2. keySet:获取所有的键
  3. entrySet:获取所有关系k-v
  4. values:获取所有的值

迭代器

System.out.println(“----使用 EntrySet 的 迭代器(第 4 种)----”);

Iterator iterator3 = entrySet.iterator();

while (iterator3.hasNext()) {

​ Object entry = iterator3.next();

//System.out.println(next.getClass());//HashMap$Node实现-> Map.Entry (getKey,getValue)

//向下转型 Map.Entry

​ Map.Entry m = (Map.Entry) entry;

​ System.out.println(m.getKey() + “-” + m.getValue()

Map 接口实现类- HashMap

HashMap 小结

1)Map接口的常用实现类:HashMap、Hashtable和Properties。

2)HashMap是Map接口使用频率最高的实现类。

3) HashMap 是以 key-val 对的方式来存储数据(HashMap$Node类型)

4)key不能重复,但是值可以重复,允许使用null键和null值

5)如果添加相同的key,则会覆盖原来的key-val,等同于修改.(key不会替换,val会替换)6)与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的.(jdk8的hashMap底层数组+链表+红黑树)

7)HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有synchronized

HashMap 底层机制及源码剖析

在这里插入图片描述

HashMap 底层机制及源码剖

>扩容机制[和HashSet相同]

1) HashMap底层维护了Node类型的数组table,默认为null

2) 当创建对象时,将加载因子(loadfactor)初始化为0.75.

3) 当添加key-val时,通过key的哈希值得到在table的索引。然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素,继续判断该元素的key和准备加入的key相是否等,如果相等,则直接替换val;如果不相等需要判断是树结构还是链表结构,做出相应处理。如果添加时发现容量不够,则需要扩容。

4) 第1次添加,则需要扩容table容量为16,临界值(threshold)为12(16*0.75)

5) 以后再扩容,则需要扩容table容量为原来的2倍(32)临界值为原来的2倍,即24,依次类推

6) 在Java8中,如果一条链表的元素个数超过 TREEIFY THRESHOLD(默认是8)并且table的大小 >= MIN TREEIFY CAPACITY(默认64),就会进行树化(红黑树)

Map 接口实现类-Hashtable

HashTable 的基本介绍

1) 存放的元素是键值对:即K-V

2) hashtable的键和值都不能为null,否则会抛出NullPointerException3)hashTable使用方法基本上和HashMap一样

4) hashTable 是线程安全的(synchronized), hashMap 是线程不安全的

Hashtable 和HashMap对比

在这里插入图片描述

Map-Properties

基本介绍

  1. Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值对的形式来保存数据。

  2. 他的使用特点和Hashtable类似

  3. Properties还可以用于从xxx.properties文件中,加载数据到Properties类对象并进行读取和修改

总结-开发中如何选择集合实现类(记住)

在这里插入图片描述

Collections工具类

Collections工具类介绍

1)Collections是一个操作 Set、List和 Map等集合的工具类

2)Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作14.17.2排序操作:(均为static方法)

2.1)reverse(List):反转 List中元素的顺序

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

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

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

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

排序操作:(均为 static 方法)

查找、替换

在这里插入图片描述

泛型

使用传统方法的问题分析

1)不能对加入到集合ArrayList中的数据类型进行约束(不安全)

2)遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响泛型的理解和好处

1)编译时,检查添加元素的类型,提高了安全性

2)减少了类型转换的次数,提高效率[说明]

3)不再提示编译警告

在这里插入图片描述

泛型介绍

理解:泛(广泛)型(类型) => Integer, String,Dog

1)泛型又称参数化类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题

2)在类声明或实例化时只要指定好需要的具体的类型即可。

3)Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮

4)泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型

泛型的语法

泛型的声明

interface 接口{}和 class类<K,V>{}

比如:List,ArrayList

说明:

1)其中,T,K,V不代表值,而是表示类型。

2)任意字母都可以。常用T表示,是Type的缩写

泛型的实例化

要在类名后面指定类型参数的值(类型)。

如:

  1. List strList = new ArrayList()
  2. List strList = new ArrayList< >()
  3. Iterator iterator = customers.iterator();

泛型使用的注意事项和细节

1.interface List{}, public class HashSet{).等等

说明:T,E只能是引用类型

看看下面语句是否正确?:

  1. List list = new ArrayList(); /OK
  2. List list2 = new ArrayList();/错误

2.在给泛型指定具体类型后,可以传入该类型或者其子类类型

3.泛型使用形式

  1. List list1 = new ArrayList();
  2. List list2 = new ArrayList<>();

3.如果我们这样写 List list3 = new ArrayList();默认给它的泛型是[E就是Object]

自定义泛型类

基本语法

class类名<T,R.>{/.….表示可以有多个泛型成员}

注意细节

1)普通成员可以使用泛型(属性、方法)

2)使用泛型的数组 不能初始化 因为数组在 new 不能确定 T 的类型就无法在内存开空间

3)静态方法中不能使用类的泛型 因为静态是和类相关的,在类加载时,对象还没有创建所以,如果静态方法和静态属性使用了泛型,JVM 就无法完成初始化

4)泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)

5)如果在创建对象时,没有指定类型,默认为Object

如:

在这里插入图片描述

  1. Tiger 后面泛型,所以我们把 Tiger 就称为自定义泛型类

  2. T, R, M 泛型的标识符, 一般是单个大写字母

  3. 泛型标识符可以有多个

自定义泛型接口

基本语法

interface接名<T, R…>{}

注意细节

1)接口中,静态成员也不能使用泛型(这个和泛型类规定一样)

2)泛型接口的类型,在继承接口或者实现接口时确定

3)没有指定类型,默认为Object

如:

在这里插入图片描述

自定义泛型方法

基本语法

修饰符<T,R.>返回类型方法名(参数列表)

注意细节

  1. 泛型方法,可以定义在普通类中,也可以定义在泛型类中

  2. 当泛型方法被调用时,类型会确定

  3. public void eat(E e) {},修饰符后没有<T,R.> eat方法不是泛型方法,而是使用了泛型

泛型的继承和通配符

1)泛型不具备继承性

List list = new ArrayList();错误示列

2)<?>:支持任意泛型类型

3)<?extends A>:支持A类以及A类的子类,规定了泛型的上限
4)<?super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/671482.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实时检测Aruco标签坐标opencv-python之添加卡尔曼滤波

在实时检测Aruco标签坐标用于定位的时候发现&#xff0c;追踪效果不是很好&#xff0c;于是在检测过程中添加了卡尔曼滤波&#xff0c;在aruco检测算法检测不到aruco标签的时候&#xff0c;调用卡尔曼滤波算法&#xff08;KalmanFilter&#xff09;&#xff0c;补偿丢失的定位的…

Rabbitmq学习

文章目录 前言RabbitMQ 1 同步调用和异步调用2 常见的MQ对比3 安装RabbitMQ4 RabbitMQ学习4.1 helloworld学习 5 Spring AMQP5.1 AMQP的入门案例(使用rabbittemplate进行消息发送和接受)5.2 RabbitMQ的workquene5.3 发布订阅模型(exchange(广播fanout 路由direct 话题topic))5.…

RK3588 修改USB/Sata/TF挂载点

文章目录 概要整体架构流程技术名词解释技术细节小结APP概要 rk3588 android12 平台的挂载点是:/storage/设备卷名(即uuid) 对上层开发不太友好,因此需要固定某个挂载点提供上层app调用。 修改后的路径效果如下: 整体架构流程 从概要图示中可知:对每个挂载点创建软连接来…

大牛分享,提高工程性能的7个简单技巧

软件性能和弹性&#xff08;恢复能力&#xff09;是用户体验的关键组成部分&#xff0c;但随着软件行业采用DevOps&#xff0c;它开始在性能和弹性方面出现不足。在软件完全失败之前&#xff0c;性能问题经常被忽略。 但是&#xff0c;我们都知道性能不会突然降低。随着软件通…

【二叉树part02】| 102.二叉树的层序遍历、226.翻转二叉树、101.对称二叉树

目录 ✿LeetCode102.二叉树的层序遍历❀ ✿LeetCode226.翻转二叉树❀ ✿LeetCode101.对称二叉树❀ ✿LeetCode102.二叉树的层序遍历❀ 链接&#xff1a;102.二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff…

Python入门(二十七)测试(二)

测试&#xff08;二&#xff09; 1.测试类2.各种断言方法3.一个要测试的类4.测试AnonymousSurvey类5.方法setUp() 1.测试类 前面我们编写了针对单个函数的测试&#xff0c;下面来编写针对类的测试。很多程序中都会用到类&#xff0c;因此证明我们的类能够正确工作大有裨益。如…

AI绘画——了解AI绘画爆火原因与工具,并生成几个端午绘画小作品

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 前言 一.AI绘画 1.AI绘画爆火原因 2.AI绘画背后原理 二.AI绘画工具介绍 1.midjour…

IDC武连峰:应用数字安全免疫力理念,促进企业在数字时代韧性发展

作者&#xff1a;IDC中国副总裁、首席分析师 武连峰 数字安全免疫力是一个企业针对各种数字安全威胁时的防御机制&#xff0c;与人体免疫力相似&#xff0c;企业数字安全免疫力包含两类&#xff1a;企业安全文化意识与合规是先天性数字安全免疫力&#xff0c;今天任何一个企业…

vue使用swiper三行轮播问题

1、轮播图设置属性slidesPerColumn:3实现不了&#xff0c;解决方案如下&#xff1a; this.scheduleData是后台请求的数据&#xff0c;通过3个一组分组转换为this.scheduleListThreede 的数据&#xff01; 2、逻辑处理如下&#xff1a; computed: { scheduleListThree: functi…

做测试不会 SQL?超详细的 SQL 查询语法教程来啦!

前言 作为一名测试工程师&#xff0c;工作中在对测试结果进行数据比对的时候&#xff0c;或多或少要和数据库打交道的&#xff0c;要和数据库打交道&#xff0c;那么一些常用的sql查询语法必须要掌握。最近有部分做测试小伙伴表示sql查询不太会&#xff0c;问我有没有sql查询语…

list赋值方法add()...和set()简介

目录 一、方法展示 二、add() 方法介绍 2.1.add&#xff08;E element&#xff09; 2.1.1源码 2.1.2.实例截图 2.1.3.Null引起的题外话 2.2.add(int index, E element) 2.2.1.源码 2.2.2.示例截图 2.2.3. add()引起IndexOutOfBoundsException简介 三、addAll()方法…

CSS查缺补漏之《媒体查询@media与BFC》

示例代码如下&#xff1a; <div class"box">世界你好</div> .box {width: 200px;height: 200px;background-color: yellow;color: white;font-size: 24px;text-align: center;line-height: 200px; } 媒体类型 媒体类型允许指定文件将如何在不同媒体上…

OpenCV——《图像平滑》结果输出对比《形态学操作》

1.图像平滑 图像平滑是一项简单且使用频率很高的图像处理方法&#xff0c;可以用来压制、弱化或消除图像中的细节、突变、边缘和噪声&#xff0c;最常见的是用来减少图像上的噪声。 常用的滤波器主要为&#xff1a; 均值滤波器&#xff1a;并不能完全消除噪声&#xff0c;只能…

【服务器】搭建hMailServer 服务实现远程发送邮件

typora-copy-images-to: upload hMailServer 是一个邮件服务器,通过它我们可以搭建自己的邮件服务,通过cpolar内网映射工具即可实现远程发送邮件,不需要使用公网服务器,不需要域名,而且邮件账号名称可以自定义. 下面以windows 10系统为环境,介绍使用方法: 1. 安装hMailServe…

小鹏G9高压平台800V电驱动实拍

近日&#xff0c;小鹏汽车董事长何小鹏在其个人社交账号上透露&#xff0c;小鹏G9正按原定计划按部就班推进节奏&#xff0c;将于8月启动预订&#xff0c;9月正式迎来上市&#xff0c;上市后很快就会启动用户交付。 图片来源&#xff1a;何小鹏官方微博 需要样件请联&#xff1…

Oracle DMP文件导入

dmp文件可以在Navicat中的 把dmp放入其中。然后用数据泵导入。遗憾的是报错 [ERR] ORA-39001: invalid argument value [ERR] ORA-39000: bad dump file specification [ERR] ORA-39143: dump file "/xxx.DMP" may be an original export dump file 改为imp工具&…

干货分享 | TSMaster标定模块自动化控制应用指南

本文目录&#xff1a; 一、TSMaster标定模块自动化控制的基础原理 1.1 TSMaster的标定系统变量 1.2 内部TSMaster调用C脚本实现标定模块的自动化控制 1.3 外部调用COM组件实现自动化标定 二、标定自动化控制场景与TSMaster实例 2.1 C脚本实现控制标定模块的启动与关闭的设…

Goby 漏洞发布|网神SecGate 3600防火墙 sys_export_conf_local_save 文件读取漏洞

漏洞名称&#xff1a;网神SecGate 3600防火墙 sys_export_conf_local_save 文件读取漏洞 English Name&#xff1a;Weaver OA PluginViewServlet Authentication Bypass Vulnerability CVSS core: 8.0 影响资产数&#xff1a;738 漏洞描述&#xff1a; 网神SecGate 3600防…

同一 tomcat 不同项目 session 共享实现

说明 这里仅讨论 同一个tomcat&#xff0c;部署了两个工程&#xff08;两个war包&#xff09;。不涉及不同tomcat,不涉及集群 背景 tomcat中的工程A包含用户登录、退出、权限控制等功能&#xff1b;工程B包含业务功能接口。工程A将用户登录信息加密响应给前端&#xff0c;前…

基于Java校园快递代取系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…