Java进阶06List集合泛型

Java进阶06 集合

一、集合及其体系结构

集合是一个长度可变的容器

1、集合的体系结构

1.1 单列集合
  • 单列集合使用add()方法添加集合元素,一次只能添加一个元素。

  • 单列集合均实现了Collection接口,该接口还有两个子接口List和Set。

    • List接口

      List集合的特点是存取有序、有索引、可以存储重复的;包含ArrayList、LinkedList两个集合

    • Set接口

      Set集合的特点是存取无序、没有索引、不可以存储重复的;包含TreeSet、HashSet、LinkedHashSet

1.2 双列集合
  • 双列集合使用put()方法添加集合元素,一次可以添加两个元素

  • 双列集合均实现了Map接口

  • 双列集合包括:TreeMap、HashMap、LinkedHashMap

二、Collection的使用

方法名说明
public boolean add(E e)把给定的对象添加到当前集合中,返回是否添加成功
public void clear()清空集合中所有的元素
public boolean remove(E e)把给定的对象在当前集合中删除,返回是否删除成功
public boolean contains(Object obj)判断当前集合中是否包含给定的对象
public boolean isEmpty()判断当前集合是否为空
public int size()返回集合中元素的个数/集合的长度

注意事项:

  • remove()、contains()底层都是依赖equals方法

  • clear()是清空集合中所有元素,不是销毁集合容器。清空后还是可以继续往集合中添加元素的

三、集合遍历方式(5种)

1、普通for循环

ArrayList<String> list = new ArrayList<>();
​
for (int i = 0; i < list.size(); i++) {String s = list.get(i);
}

2、迭代器遍历

2.1 Collection接口的方法
方法说明
public Iterator<E> iterator()获取遍历集合的迭代器对象
public boolean hasNext()判断集合中是否还有元素
public E next()取出集合中元素,并且将指针向后移动一位
2.2 迭代器遍历
public class CollectionDemo2 {public static void main(String[] args) {//多态创建集合容器,左边为接口引用,右边为实现类对象Collection<Student> c = new ArrayList<>();c.add(new Student("张三", 23));c.add(new Student("李四", 24));c.add(new Student("王五", 25));// 1. 获取迭代器  其实这句代码相当于 Iterator<Student> it = new Itr();Iterator<Student> it = c.iterator();// 2. 循环的判断, 集合中是否还有元素while (it.hasNext()) {// 3. 通过迭代器取出集合的元素Student stu = it.next();System.out.println(stu.getName() + "---" + stu.getAge());//这样调用会出现信息错乱!!!System.out.println(it.next().getName() + "---" + it.next().getAge());}}
}

注意:next()方法每调用一次,迭代器指针会后移一位,就会把不同集合元素的信息拼接到一起打印,为了避免这种信息错乱,建议在循环中,next()只调用一次

2.3 迭代器源码分析
private class Itr implements Iterator<E> {//定义游标,表示指针指向int cursor; public boolean hasNext() {//判断指针值是否等于集合长度return cursor != size;    }  public E next() { //定义i变量记录当前指针所指向的元素下标int i = cursor;        //指针后移cursor = i + 1;        //返回i队应下标所记录的元素值return (E) elementData[lastRet = i];   }
}

3、增强for循环

增强for循环是JDK5之后出现的,其内部原理就是一个Iterator迭代器,它简化迭代器的代码书写,是迭代器遍历的语法糖。

3.1 格式
for(元素的数据类型 变量名 : 数据或者集合){
}

快捷键 需要迭代的集合.for再回车

3.2 Demo
public class CollectionDemo3 {public static void main(String[] args) {Collection<Student> c = new ArrayList<>();c.add(new Student("张三", 23));c.add(new Student("李四", 24));c.add(new Student("王五", 25));
​//增强for循环遍历集合for (Student stu : c) {System.out.println(stu);}
​System.out.println("----------------------");
​//增强for循环遍历数组int[] nums = {11, 22, 33};for (int num : nums) {System.out.println(num);}}
}

注意细节:增强for循环遍历数组时,循环变量直接代表每一份元素,并不是下标。为了避免和出错和fori搞混,这个循环变量我们一般不会取名为i

4、foreach方法

//遍历集合
default void forEach(Consumer<? super I>action)

跟进源码后发现该方法需要的参数Consumer是一个接口类型,那么我们就要传入该接口的实现类对象,可以创建一个并传入。然而源码中验证该接口还是一个函数式接口,因此可以传入匿名内部类,还可以将其改写成Lambda表达式。

public class CollectionDemo4 {public static void main(String[] args) {Collection<Student> c = new ArrayList<>();c.add(new Student("张三",23));c.add(new Student("李四",24));c.add(new Student("王五",25));
​//匿名内部类写法c.forEach(new Consumer<Student>() {@Overridepublic void accept(Student student) {System.out.println(student);}});
​//Lambda表达式写法c.forEach(s-> System.out.println(s));}
}

5、ListIterator遍历

继承了Iterator,是List集合派系所特有的迭代器,遍历方式与Iterator遍历类似,但也有其特殊之处:它内部含有hasPrevious()方法和previous()方法,可以配合使用进行倒序遍历,前提是必须要先正序遍历让指针移至最后,否则倒叙遍历没有效果

public static void main(String[] args) {List<String> list = new ArrayList<>();
​list.add("张三");list.add("李四");list.add("王五");
​
​ListIterator<String> it = list.listIterator();
​//正序遍历while (it.hasNext()) {String s = it.next();System.out.println(s);}
​System.out.println("---------------------------------");
​//倒序遍历,前提必须先正序遍历让指针后移至最后,否则没有效果while (it.hasPrevious()) {String s = it.previous();System.out.println(s);}}

四、List接口

list接口因为支持索引,所以多了很多索引操作的独特API

方法名说明
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素

五、数据结构

数据结构是计算机底层存储组织数据的方式,是指数据相互之间是以什么方式排列在一起的

1、栈和队列

队列
一端开口(栈顶),一端封闭(栈底)两端均开口
栈顶出入栈队尾入队,队头出队
后进先出先进先出

2、数组和链表

数组链表
内存连续区域在内存中游离,不连续
查询速度快:通过地址和索引定位,查任意数据耗时相同查询速度慢:没有索引,无论查询哪个数据都要从头遍历
增删效率低:增删有可能大批量的移动数组中其他元素增删效率相对数组快:增删不用移动大量元素,只需修改指针即可
  • 单链表&双链表

链表元素在内存中是游离的,其中每个结点是独立的对象,在内存中不是连续的,每个结点有自己的存储地址,包含其存储的具体数据值和下一个结点的地址。见名知义,单链表即链接方向是单向的,对链表的访问要通过顺序读取从头部开始。双链表的链接方向是双向的,即每个数据结点中都有两个指针,分别指向直接后继和直接前驱。因此双向链表首尾操作极快!!!

六、ArrayList类&LinkedList类

1、ArrayList类

ArrayList底层是基于数组实现的,所以查询元素快,增删相对慢

1.1 ArrayList长度可变原理

ArrayList底层是数据结构,数组默认长度为10;当数组添加满了之后,会自动扩容为1.5倍,扩容时会先将原数组数据拷贝到新数组中,再将新元素添加到新数组

1.2 ArrayList源码解析

使用空参构造器创建的集合,在底层创建一个默认长度为0的数组

添加第一个元素时,底层会创建一个新的长度为10的数组

存满时,会扩容1.5倍

2、LinkedList类

LinkedList底层基于双链表实现的,查询元素慢,增删首尾元素是非常快的

特有方法说明
public void addFirst(E e)在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素
  • 注意:LinkedList的get()方法,表面看起来是根据索引获取元素,实际并非如此。它的原理很简答,是通过遍历链表来查找指定索引的元素。具体来说,get()方法从链表的表头开始遍历,它经过一个节点,就将计数器加一。当计数器的值等于要查找的索引时,get()方法就返回该节点的元素值,否则继续遍历直到表尾。

七、泛型

JDK5引入泛型,可以在编译阶段约束操作的数据类型,并进行检查。使用泛型的好处是:统一数据类型,将运行期的错误提升到了编译期。泛型中只能编写引用型数据,如果不指定泛型的具体类型,则系统默认创建Object对象

1、泛型类

1.1 使用场景

当类中的属性或是方法却无法确定具体类型时,可以设计泛型类

1.2 确定具体类型

在创建对象的时候确定到具体数据类型

//泛型类
public class ArrayList<E>{private E e;public E getE(){return e;}public void setE(E e){this.e = e;}
}
​
public static void main(String[] args){//创建对象,指定类型为IntegerStudent<Integer> stu = new Student<>;
}

2、泛型方法

2.1 非静态泛型方法

泛型是根据类的泛型去匹配的

public class ArrayList<E>{public boolean add(E e){}
}
2.2 静态泛型方法

需要声明出自己独立的泛型

public static<T> void printArray(T[] array){}
public class Demo3 {public static void main(String[] args) {Integer[] arr1 = {11,22,33};Double[] arr2 = {11.1,22.2,33.3};String[] arr3 = {"张三","李四","王五"};
​printArray(arr1);printArray(arr2);printArray(arr3);}
​//该方法在main函数中调用,因此必须是static修饰,又想接收各种类型,所以自己定义独立的泛型private static<T> void printArray(T[] arr) {System.out.print("[");for (int i = 0; i < arr.length-1; i++) {System.out.print(arr[i]+",");}System.out.println(arr[arr.length-1]+"]");}
}

3、泛型接口

3.1 使用场景

接口中的某个抽象方法确定不了参数的具体类型,就可以声明泛型,让该方法的泛型去匹配接口的泛型

3.2 确定具体数据类型

类实现接口时,如果接口带有泛型,有两种操作方式

  • 类实现接口的时候,直接确定类型

  • 实现类延续接口的泛型,等创建对象的时候再确定

//泛型接口
interface Inter<E>{//抽象方法的参数匹配接口的泛型void show(E e);
}
​
//类实现接口的时候直接指定类型为String
class InterAImpl implements Inter<String>{
​@Overridepublic void show(String s) {
​}
}
​
//实现类延用接口泛型,则在该实现类创建对象的时候一定要给出具体类型
class InterBImpl<E> implements Inter<E>{
​@Overridepublic void show(E e) {}
}

4、泛型通配符

书写位置在<>内,有以下三种用法

  • :任意类型

  • ?extends E:只能接收E或者E的子类

  • ?super E:只能接收E或者E的父类

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

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

相关文章

文件各种上传,离不开的表单 [html5]

作为程序员的我们&#xff0c;经常会要用到文件的上传和下载功能。到了需要用的时候&#xff0c;各种查资料。有木有..有木有...。为了方便下次使用&#xff0c;这里来做个总结和备忘。 利用表单实现文件上传 最原始、最简单、最粗暴的文件上传。 前端代码&#xff1a; //方…

简单了解泛型

基本数据类型和对应的包装类 在Java中, 基本数据类型不是继承自Object, 为了在泛型代码中可以支持基本类型, Java给每个基本类型都对应了一个包装类型. 简单来说就是让基本数据类型也能面向对象.基本数据类型可以使用很多方法, 这就必须让它变成类. 基本数据类型对定的包装类…

[Linux][网络][TCP][四][流量控制][拥塞控制]详细讲解

目录 1.流量控制2.拥塞控制0.为什么要有拥塞控制&#xff0c;不是有流量控制么&#xff1f;1.什么是拥塞窗口&#xff1f;和发送窗口有什么关系呢&#xff1f;2.怎么知道当前网络是否出现了拥塞呢&#xff1f;3.拥塞控制有哪些算法&#xff1f;4.慢启动5.拥塞避免6.拥塞发生7.快…

LabelImg下载及目标检测数据标注

为什么这一部分内容这么少会单独拎出来呢&#xff0c;因为后期会接着介绍YOLOv8中的其他任务&#xff0c;会使用其他软件进行标注&#xff0c;所以就单独区分开来每一个任务的标注方式了。 这一部分就介绍目标检测任务的标注&#xff0c;数据集是我从COCO2017Val中抽出来两类&a…

矩阵相关运算1

矩阵运算是线性代数中的一个核心部分&#xff0c;它包含了许多不同类型的操作&#xff0c;可以应用于各种科学和工程问题中。 矩阵加法和减法 矩阵加法和减法需要两个矩阵具有相同的维度。操作是逐元素进行的&#xff1a; CAB or CA−B其中 A,B 和 C 是矩阵&#xff0c;且 C…

RTT PIN设备学习

获取GPIO编号 GET_PIN(port, pin)#define LED_BLUE_PIN GET_PIN(A, 0)设置引脚模式 void rt_pin_mode(rt_base_t pin, rt_base_t mode);设置引脚电平 void rt_pin_write(rt_base_t pin, rt_base_t value);rt_base_t pin 同上&#xff0c; 为引脚编号&#xff0c;尽量通过宏定…

新建的springBoot WEB项目无法自动返回html模版(gradle+kotlin版本)

最近研究了springBoot创建web项目&#xff0c; 第一步服务端返回字符串没有问题&#xff0c;第二步返回html时&#xff0c;还是返回的字符串。 文章目录 一、参考方案二、新建springBoot web项目三、启动项目的三种方式 一、参考方案 将控制器类的 RestController 改为 Contro…

代码随想录算法训练营第六十天| 647. 回文子串,516.最长回文子序列,动态规划总结篇

题目与题解 参考资料&#xff1a;动态规划总结篇 647. 回文子串 题目链接&#xff1a;647. 回文子串 代码随想录题解&#xff1a;647. 回文子串 视频讲解&#xff1a;动态规划&#xff0c;字符串性质决定了DP数组的定义 | LeetCode&#xff1a;647.回文子串_哔哩哔哩_bilibili …

【再探】设计模式—适配器、装饰及外观模式

结构型设计模式是用于设计对象和类之间关系的一组设计模式。一共有7种&#xff1a;适配器模式、装饰器模式、外观模式、桥接模式、组合模式、享元模式及代理模式。 1 适配器模式 需求&#xff1a;在软件维护阶段&#xff0c;已存在的方法与目标接口不匹配&#xff0c;需要个中…

每日一题5:Pandas-修改列

一、每日一题 一家公司决定增加员工的薪水。 编写一个解决方案&#xff0c;将每个员工的薪水乘以2来 修改 salary 列。 返回结果格式如下示例所示。 解答&#xff1a; import pandas as pddef modifySalaryColumn(employees: pd.DataFrame) -> pd.DataFrame:employees.loc[…

最后一块石头的重量 II ,目标和,一和0

最后一块石头的重量 II&#xff08;0-1背包问题 将石头尽可能分为两堆重量一样的&#xff0c;进行相撞则为0 class Solution {public int lastStoneWeightII(int[] stones) {int sum0;for(int x:stones){sumx;}int targetsum/2;int[] dpnew int[target1];//dp[j]表示最大石堆的…

【一起深度学习-----VGG】

VGG 原理图&#xff1a; 原理图&#xff1a; 为啥要使用VGG块呢&#xff1f; 对于AlexNet网络来说&#xff0c;虽然十分高效了&#xff0c;但是它并没有提供一个通用的模板&#xff0c;方便后续的研究。 故采用了模块化的思想&#xff0c;方便重复使用。 其实对比于AlexNet神经…

必应bing国内广告怎么做付费推广,提升产品曝光?

必应Bing作为微软旗下重要的搜索引擎平台&#xff0c;拥有着不可忽视的用户基础和市场潜力。对于寻求拓宽市场、提高品牌知名度的企业而言&#xff0c;利用必应Bing进行付费推广无疑是明智之选。通过必应Bing国内广告进行高效付费推广&#xff0c;助您轻松提升产品曝光度。 一…

C++:多态-虚函数

C 中的多态性是面向对象编程中的一个重要概念&#xff0c;它允许在运行时选择不同的函数实现&#xff0c;以适应不同类型的对象。 多态的种类 编译时多态性&#xff08;Compile-time Polymorphism&#xff09;&#xff1a;也称为静态多态性或早期绑定&#xff0c;指在编译时确…

【Git】Git学习-13:Gitee和GitLab的使用

学习视频链接&#xff1a;【GeekHour】一小时Git教程_哔哩哔哩_bilibili​编辑https://www.bilibili.com/video/BV1HM411377j/?vd_source95dda35ac10d1ae6785cc7006f365780 流程 1. 创建仓库/已有仓库 2. 克隆到本地/在远程仓库关联 git clone 仓库地址 git remote add 仓库别…

[Kotlin]创建一个私有包并使用

1.创建Kotlin项目 创建项目&#xff1a; 在Android Studio或其他IDE中选择“Create New Project”。选择Kotlin和Gradle作为项目类型和构建系统。指定项目名称和位置&#xff0c;完成设置。 添加依赖: 如果你的库需要额外的依赖&#xff0c;可以在 build.gradle (Module: app…

Axure中继器介绍以及案例分享

中继器是 Axure 中一个比较高阶的应用&#xff0c;它可以让我们在纯静态网页中模拟出类似带有后台数据交互的增删改查的效果。 一、中继器的基本使用方法&#xff1a; 整体流程分为三个步骤 ☆创建中继器 我们先在 Axured画布中拖入一个中继器元件 双击中继器后的效果 打开之…

APP 在华为应用市场上架 保姆级别详细流程

1、作为一名干开发的程序员&#xff0c;第一次能把自己的APP 上架&#xff0c;对自己来说是多么有意义的一项成就 2、创建一个 华为的开发者账号 根据提示填写完注册的信息https://developer.huawei.com/consumer/cn/product/华为开发者产品 | 开发者平台 | 流量变现 | 华为开…

商家制作微信小程序有什么好处?微信小程序的制作有哪些步骤和流程

微信小程序全面指南 微信小程序是微信生态系统中一项革命性的功能&#xff0c;为希望与庞大的微信用户群体互动的企业提供了独特的融合便捷性和功能性的体验。本全面指南深入探讨了微信小程序的世界&#xff0c;强调了其重要性、工作原理以及实际用例&#xff0c;特别是针对企…

CCE云原生混部场景下的测试案例

背景 企业的 IT 环境通常运行两大类进程&#xff0c;一类是在线服务&#xff0c;一类是离线作业。 在线任务&#xff1a;运行时间长&#xff0c;服务流量及资源利用率有潮汐特征&#xff0c;时延敏感&#xff0c;对服务SLA 要求高&#xff0c;如电商交易服务等。 离线任务&…