08_Collection集合2

List 集合

特点与方法

List 系列集合:添加的元素是有序、可重复、有索引

import java.util.ArrayList;
import java.util.List;public class Test {public static void main(String[] args) {// 1. 创建一个 ArrayList 集合对象List<String> lst = new ArrayList<>();lst.add("Jack");lst.add("Peter");lst.add("Tony");System.out.println(lst);  // [Jack, Peter, Tony]// 2. 在某索引位置,插入元素lst.add(1,"Tomato");System.out.println(lst);  // [Jack, Tomato, Peter, Tony]// 3. 带走某个索引的元素System.out.println(lst.remove(1));  // TomatoSystem.out.println(lst);  // [Jack, Peter, Tony]// 4. 返回某索引的元素System.out.println(lst.get(2));  // Tony// 5. 修改索引位置处的元素,修改成功后,会返回原来的数据System.out.println(lst.set(2, "Wang"));  // TonySystem.out.println(lst);  // [Jack, Peter, Wang]}
}
遍历方式
  • for 循环(因为 List 集合有索引)
  • 迭代器
  • 增强 for 循环
  • Lambda 表达式

具体代码演示省略,请参照其父类

底层原理

ArrayList 集合的底层原理

  • 基于数组实现

  • 特点

    查询速度快(通过索引)

    删除效率低

    添加效率低

LinkedList 集合的底层原理

  • 基于双链表实现

  • 特点

    查询速度慢

    增加和删除相对较快

  • 应用场景:可以用来设计队列,也可以设计栈

// 模拟队列import java.util.LinkedList;public class Test {public static void main(String[] args) {// 1. 创建一个队列LinkedList<String> queue = new LinkedList<>();// 入队queue.addLast("第1号人");queue.addLast("第2号人");queue.addLast("第3号人");queue.addLast("第4号人");System.out.println(queue);// 出队System.out.println(queue.removeFirst());System.out.println(queue.removeFirst());System.out.println(queue.removeFirst());System.out.println(queue);}
}
// 模拟栈import java.util.LinkedList;public class Test {public static void main(String[] args) {// 1. 创建一个栈LinkedList<String> stack = new LinkedList<>();// 入栈(push)stack.addFirst("第1颗子弹");  // 等价于stack.push("第1颗子弹")stack.addFirst("第2颗子弹");  // 注意,官方的push背后的本质就是stack.addFirst()stack.addFirst("第3颗子弹");stack.addFirst("第4颗子弹");System.out.println(stack);// 出栈(pop)System.out.println(stack.removeFirst());  // 等价于stack.pop()System.out.println(stack.removeFirst());  // 官方pop背后的本质就是stack.removeFirst()System.out.println(stack.removeFirst());System.out.println(stack);}
}

Set 集合

特点
  • 无序、不重复、无索引
  • Set 要用到的常用方法,基本上就是 Collection 提供的!自己几乎没有额外新增的常用功能
HashSet 集合的底层原理

HashSet 集合:无序、不重复、无索引

哈希值

  • 就是一个 int 类型的数值,Java 中每个对象都有一个哈希值
  • Java中的所有对象,都可以调用 Object 类提供的 hashCode 方法,返回该对象自己的哈希值

对象哈希值的特点

  • 同一个对象多次调用 hashCode() 方法返回的哈希值是相同的
  • 不同的对象,它们的哈希值一般不相同,但也有可能相同(哈希碰撞)

底层原理

  • 基于哈希表实现
  • 哈希表是一种增删改查数据,性能都较好的数据结构

哈希表

  • JDK 8 之前:哈希表 = 数值 + 链表
  • JDK 8 之后:哈希表 = 数值 + 链表 + 红黑树

补充:如果希望 Set 集合认为2个内容一样的对象是重复的,必须重写对象的 hashCode() 和 equals() 方法

import java.util.Objects;public class Test {public static void main(String[] args) {Student s1 = new Student("Jack", 20);Student s2 = new Student("Tony", 25);Student s3 = new Student("Tony", 25);// 哈希值System.out.println(s1.hashCode());  // 71329718System.out.println(s2.hashCode());  // 80993012System.out.println(s3.hashCode());  // 80993012System.out.println(s2.hashCode() == s3.hashCode());  // true}
}class Student {private String name;private int age;// 重写 equals 方法@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}// 重写 hashCode 方法@Overridepublic int hashCode() {return Objects.hash(name, age);}public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
LinkedHashSet 集合

LinkedHashSet 集合:有序、不重复、无索引

底层原理

  • 依然是基于哈希表(数值、链表、红黑数)实现的
  • 但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置
TreeSet 集合

TreeSet 集合:不重复、无索引、可排序(默认升序排序)

底层是基于红黑树实现的排序

import java.util.Set;
import java.util.TreeSet;public class Test {public static void main(String[] args) {Set<Integer> set1 = new TreeSet<>();set1.add(6);set1.add(5);set1.add(5);set1.add(7);System.out.println(set1);  // [5, 6, 7]}
}

对于自定义类型,如 Student 对象,TreeSet 默认是无法直接排序的(会报错)

import java.util.Set;
import java.util.TreeSet;public class Test {public static void main(String[] args) {// 未简化的
//        Set<Student> set1 = new TreeSet<>(new Comparator<Student>() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                return Double.compare(o1.getHeight(), o2.getHeight());
//            }
//        });// lambda 简化后Set<Student> set1 = new TreeSet<>((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()));set1.add(new Student("Jack", 25, 51.2));set1.add(new Student("Tony", 18, 77.9));set1.add(new Student("Peter", 33, 65.8));System.out.println(set1);// [Student{name='Jack', age=25, height=51.2}, Student{name='Peter', age=33, height=65.8}, Student{name='Tony', age=18, height=77.9}]}
}class Student {private String name;private int age;private double height;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", height=" + height +'}';}public Student() {}public Student(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}
}
注意事项:集合的并发修改异常问题

注意:使用迭代器遍历集合的时候,又同时在删除集合中的数据,程序就会出现并发修改异常的错误。

产生问题的原因:当我们正向的进行"迭代"或者 for 循环时,变量 i 指向了需要被删除的元素,我们成功删除对象后,其后面的所有元素会立刻前移,此时变量 i 的指向却还是停留原地,这就导致了指向的不匹配!这个问题,在 for 循环中不会报错,但是无法完成业务,而且较难发现问题所在,为了避免这个问题的难以发现,迭代器就贴心的为我们进行了报错,

解决办法

  • 如果能使用 for 循环遍历:可以倒着遍历并删除;或者从前往后遍历,但删除元素后做 i - - 操作
  • 使用迭代器遍历集合,但用迭代器自己的删除方法删除数据即可(其方法的本质上是做了类似 i - - 的操作)

Collection 其他内容

可变参数
import java.util.Arrays;public class Test {public static void main(String[] args) {// 可变参数run();run(10);run(10, 20, 30);run(10, 20, 30, 40);// 运行结果:// []// [10]// [10, 20, 30]// [10, 20, 30, 40]}// 注意事项:// 1. 一个形参列表中,只能有一个可变参数// 2. 可变参数必须放在形参列表的最后面public static void run(int... nums) {// 可变参数在方法内部,本质就是数组System.out.println(Arrays.toString(nums));}
}
Collections
  • 注意!它不是 Collection 集合,它多了个"s"
  • Collections 是一个用来操作集合的工具类
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;public class Test {public static void main(String[] args) {// 1. 为集合批量添加数据List<String> lst = new ArrayList<>();Collections.addAll(lst, "Jack", "Peter", "Tony");System.out.println(lst);  // [Jack, Peter, Tony]// 2. 打乱List集合里面的元素顺序Collections.shuffle(lst);System.out.println(lst);  // [Peter, Tony, Jack]// 3. 对List集合里面的元素进行升序排序List<Integer> lst2 = new ArrayList<>();lst2.add(3);lst2.add(5);lst2.add(1);System.out.println(lst2);  // [3, 5, 1]Collections.sort(lst2);System.out.println(lst2);  // [1, 3, 5]// 4. 自定义的对象如何排序List<Student> lst3 = new ArrayList<>();lst3.add(new Student("Jack", 25, 51.2));lst3.add(new Student("Tony", 18, 77.9));lst3.add(new Student("Peter", 33, 65.8));Collections.sort(lst3, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return Double.compare(o1.getHeight(), o2.getHeight());}});}
}class Student {private String name;private int age;private double height;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", height=" + height +'}';}public Student() {}public Student(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}
}

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

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

相关文章

IP-Adapter:文本兼容图像提示适配器,用于文本到图像扩散模型

IP-Adapter这是一种有效且轻量级的适配器&#xff0c;用于实现预训练文本到图像扩散模型的图像提示功能。只有 22M 参数的 IP 适配器可以实现与微调图像提示模型相当甚至更好的性能。IP-Adapter 不仅可以推广到从同一基本模型微调的其他自定义模型&#xff0c;还可以推广到使用…

软件工程理论与实践 (吕云翔)第十四章 软件维护与软件工程管理课后习题与解析

第十四章 软件维护与软件工程管理 1.判断题 &#xff08;1&#xff09;代码行技术是比较简单的定量估算软件规模的方法。(√) &#xff08;2&#xff09;功能点技术依据对软件信息域特性和软件复杂性的评估结果&#xff0c;估算软件规模。&#xff08;√&#xff09; &#…

前端js优化表单中单个输入框的回车提交事件

前提 当表单内只有一个input输入框时&#xff0c;即使表单没有submit按钮&#xff0c;在输入框内按下回车键就会触发表单的提交事件。这可能会导致一些意外的行为&#xff0c;特别是当用户不希望提交表单时。 为了解决这个问题&#xff0c;我们可以采取以下两种优化方法&…

机器学习(1)机器学习类型和机器学习的主要概念

0.前提 深度学习&#xff08;Deep Learing&#xff09;是机器学习&#xff08;Machine Learning&#xff09;领域中的一个新的研究方向&#xff0c;在如今的时代研究深度学习的大模型是十分热门的。我不知道有多少人有关注到最近openai的事件啊&#xff0c;说个比较让我惊讶的…

03、K-means聚类实现步骤与基于K-means聚类的图像压缩(1)

03、K-means聚类实现步骤与基于K-means聚类的图像压缩&#xff08;1&#xff09; 03、K-means聚类实现步骤与基于K-means聚类的图像压缩&#xff08;1&#xff09; 03、K-means聚类实现步骤与基于K-means聚类的图像压缩&#xff08;2&#xff09; 开始学习机器学习啦&#xf…

解决:ModuleNotFoundError: No module named ‘PyQt5‘

解决&#xff1a;ModuleNotFoundError: No module named ‘PyQt5’ 文章目录 解决&#xff1a;ModuleNotFoundError: No module named PyQt5背景报错问题报错翻译报错位置代码报错原因解决方法安装PyQt5在PyCharm中配置PyQt5对于新项目对于已有项目 今天的分享就到此结束了 背景…

【序列推荐】MAN:跨领域顺序推荐的混合注意网络

#论文题目&#xff1a;MAN&#xff1a;Mixed Attention Network for Cross-domain Sequential Recommendation&#xff08;跨领域顺序推荐的混合注意网络&#xff09; #论文地址&#xff1a;https://dl.acm.org/doi/10.1145/3543507.3583278 #论文源码开源地址&#xff1a;http…

Docker可视化工具Portainer(轻量)或者Docker容器监控之 CAdvisor+InfluxDB+Granfana(重量)

Docker轻量级可视化工具Portainer 是什么 Portainer 是一款轻量级的应用&#xff0c;它提供了图形化界面&#xff0c;用于方便地管理Docker环境&#xff0c;包括单机环境和集群环境。 安装 官网 https://www.portainer.io/ https://docs.portainer.io/v/ce-2.9/start/instal…

CANdelaStudio 中 Bese Variant 和 Variant区别

关于 Bese Variant &#xff0c;其在 CDDT 和 CDD 文件中都存在&#xff0c;有且只有一个 主要包含三部分&#xff0c;重点只关注 DIDs 和 Supported Diagnostic Classes 而在 CDD 文件中&#xff0c;除了 Bese Variant 外&#xff0c;还有一个 Variant “Variant” 这个概…

minio分布式存储系统

目录 拉取docker镜像 minio所需要的依赖 文件存放的位置 手动上传文件到minio中 工具类上传 yml配置 config类 service类 启动类 测试类 图片 视频 删除minio服务器的文件 下载minio服务器的文件 拉取docker镜像 拉取稳定版本:docker pull minio/minio:RELEASE.20…

解析和存储优化的批量爬虫采集策略

如果你正在进行批量爬虫采集工作&#xff0c;并且想要优化解析和存储过程&#xff0c;提高采集效率和稳定性&#xff0c;那么本文将为你介绍一些实用的策略和技巧。解析和存储是批量爬虫采集中不可忽视的重要环节&#xff0c;其效率和质量对整个采集系统的性能至关重要。在下面…

前端 --- HTML

目录 一、网络的三大基石 ​二、什么是HTML 一、HTML 指的是超文本标记语言 二、HTML的作用 三、HTML的标准结构 四、IDE_HBuilder的使用 一、编码工具&#xff1a; 二、集成开发环境 三、HBuilder使用步骤&#xff1a; 五、HTML的标签的使用 一、html_head_body 二、head…

视频字幕处理+AI绘画,Runway 全功能超详细使用教程(4)

runway的视频字幕处理、AI绘图功能介绍&#xff0c;感觉完全就是为了做电影而布局&#xff0c;一整套功能都上线了&#xff01;想系统学习的必收藏&#xff01; 在深度研究Runway各个功能后&#xff0c;无论是AI视频生成及后期处理技术&#xff0c;还是AI图像生成技术&#xff…

浮点数在内存中的存储

浮点数的存储 根据国际标准IEEE&#xff0c;任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式&#xff1a; V (−1) ^S∗ M ∗ 2^E • (−1)^ S 表⽰符号位&#xff0c;当S0&#xff0c;V为正数&#xff1b;当S1&#xff0c;V为负数 • M 表⽰有效数字&#xff0c;M是⼤于…

原生DOM事件、react16、17和Vue合成事件

目录 原生DOM事件 注册/绑定事件 DOM事件级别 DOM0&#xff1a;onclick传统注册&#xff1a; 唯一&#xff08;同元素的(不)同事件会覆盖&#xff09; 没有捕获和冒泡的&#xff0c;只有简单的事件绑定 DOM2&#xff1a;addEventListener监听注册&#xff1a;可添加多个…

ES的“或“查询

场景&#xff1a;需要查询ES中userId为""或者userId字段不存在的数据 dsl语句&#xff1a; {"from": 0,"size": 30,"query": {"bool": {"should": [{"term": {"userId": {"value"…

使用mock.js模拟数据

一、安装mock.js npm i mockjs 二、配置JSON文件 我们创建一个mock文件夹&#xff0c;用于存放mock相关的模拟数据和代码实现。 我们将数据全部放在xxx.json文件夹下&#xff0c;里面配置我们需要的JSON格式的数据。 注意&#xff1a;json文件中不要留有空格&#xff0c;否则…

Spring之AOP理解与应用(更新中)

1. AOP的认识 面向切面编程&#xff1a;基于OOP基础之上新的编程思想&#xff0c;OOP面向的主要对象是类&#xff0c;而AOP面向的主要对象是切面&#xff0c;在处理日志、安全管理、事务管理等方面有非常重要的作用。AOP是Spring中重要的核心点&#xff0c;AOP提供了非常强…

GDOUCTF2023-Reverse WP

文章目录 [GDOUCTF 2023]Check_Your_Luck[GDOUCTF 2023]Tea[GDOUCTF 2023]easy_pyc[GDOUCTF 2023]doublegame[GDOUCTF 2023]L&#xff01;s&#xff01;[GDOUCTF 2023]润&#xff01;附 [GDOUCTF 2023]Check_Your_Luck 根据 if 使用z3约束求解器。 EXP&#xff1a; from z3 i…

万字解析设计模式之迭代器模式、备忘录模式

一、迭代器模式 1.1概述 迭代器模式是一种行为型设计模式&#xff0c;它允许在没有暴露其底层表现形式的情况下遍历集合对象。迭代器模式提供一种通用的遍历机制&#xff0c;可以遍历任何类型的集合&#xff0c;包括数组、列表、树等。通过这种模式&#xff0c;可以实现一种通…