集合深入------理解底层。

集合的使用

前提:栈、堆、二叉树、hashcode、toString()、quesalus()的知识深入和底层理解。

1、什么是集合

集合就是咋们所说的容器
​
前面我们学习过数组  数组也是容器
​
容器:装东西的  生活中有多少的容器呀?  水杯  教室  酒瓶  水库  只要是能装东西的 都可以看成是容器
​
我们这个集合的容器 是用来装啥的呢?  装数据?
​
数据? 一切可以被计算机识别的 文字  图片  视频  音频都是数据
​
说白了 我们今天所学习的这个集合 就跟前面的数组类似  只是底层的实现不一样而已

2、集合的分类

主要根据我们的值的个数 可以分成 单例集合 和  双列集合
​
单例集合:简单的说 在这个容器中存放的的值 就是一个一个的  value单列集合的爹:Collection
​
双列集合:他在容器中存储的数据就是  键值对  key---value双列集合的爹:Map

3、单列集合

3.1、List集合
3.1.1、ArrayList
ArrayList<E>   这个集合中的泛型:表示的意思其实就是对这个容器中能存放数据类型的一种约束  比如我们的泛型的数据类型是:User  那么这个容器中只能存放User类型的数据
​
这个ArrayList底层就是数组 他是有序的  地址空间是连续的  地址空间连续 就意味着能通过开始地址+偏移量来为访问 而且能重复添加数据
​
有序:一定能通过下标访问数据
​
List中所有的内容都是可以重复的....
3.1.1.1、集合的使用
public class ArrayListTest {
​public static void main(String[] args) {//第一种方式List<String> list = new ArrayList<>();//接下来就可以向这个集合中存放数据了...list.add("123");list.add("456");list.add("789");list.add("789");
​List<String> list2 = new ArrayList<>();//接下来就可以向这个集合中存放数据了...list.add("12322");list.add("45622");
​
​//将list2集合中的数据 添加到 list中来list.addAll(list2);
​
​//能不能删除数据呢?//这个就是直接删除某一个元素list.remove("789");
​//还可以通过下标删除list.remove(0);
​
​//接下来玩下修改呢?list.set(0,"小波波");
​//获取某一个位置的元素String s = list.get(0);
​//判断这个集合中是否存在某一个元素boolean contains = list.contains("789");
​//判断集合是否为空boolean empty = list.isEmpty();
​//返货某一个元素的下标位置int i = list.indexOf("789");
​//截取集合中指定位置的元素 生成一个新的集合List<String> stringList = list.subList(0, 5);
​System.out.println("list集合的size:"+list.size());
​List<User> userList=new ArrayList<>();userList.add(new User(1,"小小","123"));userList.add(0,new User(0,"这里是测试","xxx"));
​System.out.println("userList集合的size:"+userList.size());System.out.println("userList中的数据是:"+userList.get(0));}
}
public class ArrayListTest1 {
​public static void main(String[] args) {List<String> list = new ArrayList<>();//接下来就可以向这个集合中存放数据了...list.add("123");list.add("456");list.add("789");list.add("789");
​//第一种遍历方式:因为这个ArrayList本身底层是数组(Object类型的数组) 数组地址空间连续 所以我们能通过下标来访问for (int i = 0; i <list.size() ; i++) {System.out.println("集合中的值:"+list.get(i));}System.out.println("------------------------------");
​
​//第二种遍历方式 通过增强的for循环来玩for (String val:list){System.out.println("集合中的值:"+val);}
​
​System.out.println("------------------------------");
​
​//第三种遍历方式通过JDK8中的stream流来遍历list.stream().forEach(val->{System.out.println("集合中的值:"+val);});
​System.out.println("------------------------------");
​//第四种遍历方式:迭代器  迭代器的游标问题/*** 这种情况下不允许对元素进行修改和删除** 其实不止是这种情况 在遍历的情况下 逻辑上都允许修改和删除的产生*/Iterator<String> it = list.iterator();// it.hasNext():判断下一个节点是否有元素while (it.hasNext()){//  it.next() :取出当前位置的元素String val = it.next();System.out.println("通过迭代器取出来的值:"+val);}
​System.out.println("------------------------------");
​//第五种遍历方式ListIterator<String> it1 = list.listIterator();while (it1.hasNext()){String next = it1.next();System.out.println("通过迭代器取出来的值:"+next);}}
}
3.1.2、LinkedList
LinkedList底层是链表 
​
链表中包含 一个一个的链条   每一个链条都包含了两部分
​
当前节点的值  和 下一个元素的地址
​
链表中 数据存储的地址空间不连续  所以不能使用偏移量来访问

输出的值是连续的。

public class LinkedListTest01 {
​public static void main(String[] args) {//申明对象List<String> linkedList1 = new LinkedList<>();linkedList1.add("001");linkedList1.add("002");linkedList1.add("003");linkedList1.add("004");
​for (int i = 0; i < linkedList1.size(); i++) {String val = linkedList1.get(i);System.out.println("val:"+val);}for (String val:linkedList1){System.out.println("val:"+val);}
​linkedList1.stream().forEach(val->{System.out.println("val:"+val);});}
}
​
3.1.3、Vector的使用(不常用)
这个底层也是数组  线程安全的  效率不高
​
这个集合基本不使用 不也用记住
public class VectorTest {public static void main(String[] args){List<String> vector=new Vector<>();vector.add("中国好");vector.add("小日子");for (int i = 0; i <vector.size() ; i++) {System.out.println("数据是:"+vector.get(i));}
​}
}
3.1.4、Stack(栈)
public class StackTest {
​public static void main(String[] args){//这个其实是栈的数据结构
​Stack<String> list=new Stack<String>();list.push("1");list.push("2");list.push("3");list.push("4");list.push("5");
​System.out.println("pop:"+list.pop());System.out.println("pop:"+list.pop());System.out.println("pop:"+list.pop());System.out.println("pop:"+list.pop());System.out.println("pop:"+list.pop());
​}
}
3.2、Set集合
逻辑上 Set集合逻辑上是无序的  而且Set集合能排重  不能通过下标直接访问Set<E> 的爹 依然是Collection   Set这个接口是所有Set集合的爹Set排重的原则是啥?如果在Set集合中存放的是对象比如User 那么他就首先会去调用这个User中的 hashCode方法 然后获取到当前的这个要添加数据的hashCode值去和已经添加数据的HashCode值 做比较 如果是不等 那么说明肯定不是一个元素 那么直接添加元素  如果是HashCode值 遇到了在已经添加的数据中的HashCode值是相等的话 那么都说明有可能这个值是重复的 如果是这个值是重复的话 那就去调用当前这个对象的equals方法 判断equals方法是不是返回true  如果返回true 那么说明值重复  不添加数据  如果返回的是false  那么说明值 不重复 那么就可以添加数据
3.2.1、Set集合的排重问题(HashSet)
 public static void main(String[] args) {Set<String> set = new HashSet<>();set.add("123");set.add("345");set.add("234");set.add("345");System.out.println("数据的个数:" + set.size());System.out.println("-----------------------------");Set<User> setUser = new HashSet<>();setUser.add(new User(1, "小小", "112"));setUser.add(new User(1, "小小", "134"));setUser.add(new User(1, "小小", "165"));setUser.add(new User(1, "小小", "178"));System.out.println("数据的个数:" + setUser.size());}
public class User {private Integer id;private String username;private String password;
​public User(Integer id, String username, String password) {this.id = id;this.username = username;this.password = password;}
​public User() {}
​public Integer getId() {return id;}
​public void setId(Integer id) {this.id = id;}
​public String getUsername() {return username;}
​public void setUsername(String username) {this.username = username;}
​public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
​@Overridepublic int hashCode() {return this.username.hashCode();}
​/*** 用户名一样 那么我们就认为这是同一个数据* @param obj* @return*/@Overridepublic boolean equals(Object obj) {if(obj instanceof User){User user= (User) obj;return this.username.equals(user.getUsername());}return false;}
}
3.2.2、Set集合的遍历问题(HashSet)
public class HashSetTest1 {
​public static void main(String[] args) {Set<User> set = new HashSet<>();set.add(new User(1,"xiaobobo","123"));set.add(new User(-1,"tiedan","777"));set.add(new User(3,"gousheng","0"));set.add(new User(4,"gouwa","234"));set.add(new User(1,"ergouzi","234"));
​//通过增强的for循环能访问for (User val:set){System.out.println("数据:"+val);}
​System.out.println("--------------------------");
​Iterator<User> it = set.iterator();while (it.hasNext()){User next = it.next();System.out.println("拿到的数据是:"+next);}
​System.out.println("--------------");set.stream().forEach(user -> {System.out.println("读取到的数据是:"+user);});}
}
​
3.2.3、LinkedHashSet的使用
这个集合的底层是链表
​
这个集合的数据保存是有序的
public class LinkedHashSetTest {public static void main(String[] args) {Set<User> set = new LinkedHashSet<>();set.add(new User(1, "xiaobobo", "123"));set.add(new User(-1, "tiedan", "777"));set.add(new User(3, "gousheng", "0"));set.add(new User(4, "gouwa", "234"));set.add(new User(1, "gouwa", "234"));Iterator<User> it = set.iterator();while (it.hasNext()) {User next = it.next();System.out.println(next);}}
}
3.2.4、TreeSet(底层实现是红黑树)
TreeSet和其他的Set集合一样 具有 排重的特性
​
TreeSet的底层是红黑树--->二叉树--->数据结构--->有大小关系
​
TreeSet集合自动具有排序的功能
​
这个排序 就涉及到一个大小的问题
​
自然数的大小  
​
字符串如何比较大小呢?  unicode编码值
3.2.5、两个字符串如何比较大小呢?通过编码
// 在String这个类中为我们提供了这个比较两个字符串大小的方法 
public static void main(String[] args) {String str = "Ab";String str2 = "Ab";/*** 返回值 0:表示的是前后相等* 返回值-1:表示的是前面小于后面* 返回值是1:表示的是前面大于后面*/System.out.println(str2.compareTo(str));
}
3.2.6、TreeSet的使用
TreeSet的底层使用的是红黑树来实现的
3.2.6.1、TreeSet的基本使用
package com.qfedu.edu.collection.set;
​
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
​
​
public class TreeSetTest {
​public static void main(String[] args) {Set<Integer> set = new TreeSet<>();set.add(123);set.add(0);set.add(345);set.add(77);set.add(77);set.add(89);
​//遍历这些数据Iterator<Integer> it = set.iterator();
​while (it.hasNext()) {Integer next = it.next();System.out.println("数据是:" + next);}
​//--------------下面研究字符串的排序------------System.out.println("-------------------");
​Set<String> setStr = new TreeSet<>();setStr.add("Abc");setStr.add("Bc");setStr.add("Ac");
​//遍历这些数据Iterator<String> it1 = setStr.iterator();
​while (it1.hasNext()) {String next = it1.next();System.out.println("数据是:" + next);}
​}
}
​
3.2.6.2、Comparable接口实现对象的比较

1、编写Employee对象

public class Employee implements Comparable<Employee>{
​private Integer id;private String name;private Integer salary;private String address;
​public Employee(Integer id, String name, Integer salary, String address) {this.id = id;this.name = name;this.salary = salary;this.address = address;}
​public Employee() {}
​public Integer getId() {return id;}
​public void setId(Integer id) {this.id = id;}
​public String getName() {return name;}
​public void setName(String name) {this.name = name;}
​public Integer getSalary() {return salary;}
​public void setSalary(Integer salary) {this.salary = salary;}
​public String getAddress() {return address;}
​public void setAddress(String address) {this.address = address;}
​/*** 比较的方法*    你需要按照谁排序 那么下面你就按照什么来比较**      我要通过薪资排序*         薪资是int类型 那么下面就直接做减法* @param o the object to be compared.* @return*/
//    @Override
//    public int compareTo(Employee o) {
//        return this.salary-o.getSalary();
//    }
​/*** 下面演示通过姓名来排序*  姓名是字符串类型* @param o the object to be compared.* @return*//*   @Overridepublic int compareTo(Employee o) {return this.getName().compareTo(o.getName());}*/
​/*** 如果薪资不为空 那么按照薪资排序*   如果薪资为空 并且姓名不为空 那么按照姓名排序*   如果姓名为空 那么就按照id排序....* @param o the object to be compared.* @return*/@Overridepublic int compareTo(Employee o) {if(o.getSalary()!=null){return this.getSalary()-o.getSalary();}else if(o.getName()!=null&&!("".equals(o.getName()))){return this.getName().compareTo(o.getName());}else{return this.id-o.getId();}}
​@Overridepublic String toString() {return "Employee{" +"id=" + id +", name='" + name + '\'' +", salary=" + salary +", address='" + address + '\'' +'}';}
}
​

2、编写测试类

public class TreeSetTest1 {
​public static void main(String[] args) {
​Set<Employee> set = new TreeSet<>();set.add(new Employee(1,"xiaobobo",3500,"四川成都"));set.add(new Employee(2,"xiaowangzi",1800,"四川巴中"));set.add(new Employee(3,"tiedan",2600,"四川自贡"));set.add(new Employee(4,"gousheng",15000,"四川绵阳"));set.add(new Employee(5,"gouwa",2700,"四川德阳"));
​
​Iterator<Employee> iterator = set.iterator();while (iterator.hasNext()){Employee next = iterator.next();System.out.println("获取到的数据是:"+next);}}
}
​
3.2.6.3、使用Comparator来实现对象的排序

1、对象的编写

public class Employee1{
​private Integer id;private String name;private Integer salary;private String address;
​public Employee1(Integer id, String name, Integer salary, String address) {this.id = id;this.name = name;this.salary = salary;this.address = address;}
​public Employee1() {}
​public Integer getId() {return id;}
​public void setId(Integer id) {this.id = id;}
​public String getName() {return name;}
​public void setName(String name) {this.name = name;}
​public Integer getSalary() {return salary;}
​public void setSalary(Integer salary) {this.salary = salary;}
​public String getAddress() {return address;}
​public void setAddress(String address) {this.address = address;}
​
​@Overridepublic String toString() {return "Employee{" +"id=" + id +", name='" + name + '\'' +", salary=" + salary +", address='" + address + '\'' +'}';}
}
​

2、测试的编写

package com.qfedu.edu.collection.set;
​
import com.qfedu.edu.pojo.Employee;
import com.qfedu.edu.pojo.Employee1;
​
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
​
/*** @author xiaobobo* @title: TreeSetTest* @projectName CD-Java-JY-2401-Simple-Parent* @description: 这个研究下TreeSet的对象的排序问题* @date 2024/3/19  15:26*/
public class TreeSetTest2 {
​public static void main(String[] args) {
​Set<Employee1> set = new TreeSet<>(new MyComparator());set.add(new Employee1(1,"xiaobobo",3500,"四川成都"));set.add(new Employee1(2,"xiaowangzi",1800,"四川巴中"));set.add(new Employee1(3,"tiedan",2600,"四川自贡"));set.add(new Employee1(4,"gousheng",15000,"四川绵阳"));set.add(new Employee1(5,"gouwa",2700,"四川德阳"));
​Iterator<Employee1> iterator = set.iterator();while (iterator.hasNext()){Employee1 next = iterator.next();System.out.println("获取到的数据是:"+next);}
​
​}
​
​/*** 自定义了一个比较器 这个跟上一个接口是一样的*/static class MyComparator implements Comparator<Employee1>{/**** @param o1 新数据* @param o2 老数据*  按照薪资排序  做减法 按照谁排序 就用谁来做比较* @return*/@Overridepublic int compare(Employee1 o1, Employee1 o2) {return o1.getSalary()-o2.getSalary();}}
}

4、双列的集合

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

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

相关文章

Mysql的存储引擎

目录 1.存储引擎概念 2.常用的存储引擎 2.1MyISAM 2.1.1MyISAM的特点 2.1.2MyISAM表支持3种不同的存储格式&#xff1a; 2.1.3MyISAM适用的生产场景举例 2.2InnoDB 2.2.1InnoDB特点介绍 2.2.2InnoDB适用生产场景分析 2.2.3InnoDB与MyISAM 区别 3.企业选择存储引擎依据…

C++ 扫描当前路径下文件并删除大文件

C 扫描当前路径下文件并删除大文件 C获取当前路径扫描文件路径下规定后缀名称的文件计算文件大小 1. 获取当前路径 使用<Windows.h>中的GetCurrentDirectory方法实现&#xff0c;单独编写验证程序如下&#xff1a; #include<iostream> #include<Windows.h&g…

Kotlin零基础入门到进阶实战

教程介绍 Kotlin现在是Google官方认定Android一级开发语言&#xff0c;与Java100%互通&#xff0c;并具备诸多Java尚不支持的新特性&#xff0c;每个Android程序员必备的Kotlin课程&#xff0c;每个Java程序员都需要了解的Kotlin&#xff0c;掌握kotlin可以开发Web前端、Web后…

pytorch中tensor类型转换的几个函数

目录 IntTensor转FloatTensor FloatTensor转IntTensor Tensor类型变为python的常规类型 IntTensor转FloatTensor .float函数&#xff1a; FloatTensor转IntTensor .int函数 Tensor类型变为python的常规类型 item函数

java项目将静态资源中的文件转为浏览器可访问的http地址

新增一个类叫啥无所谓&#xff0c;主要是实现 WebMvcConfigurer 加上注解 Configuration项目启动时加入bean中 只操作addResourceHandlers这一个方法 其他都没用 文章下方附带一个简易的上传图片代码 package cn.exam.config;import org.springframework.context.annotati…

STM32学习笔记(2)- 软件keil5安装和新建工程

无人问津也好&#xff0c;技不如人也罢&#xff0c;都应静下心来&#xff0c;去做该做的事。 最近在学STM32&#xff0c;所以也开贴记录一下主要内容&#xff0c;省的过目即忘。视频教程为江科大&#xff08;改名江协科技&#xff09;&#xff0c;网站jiangxiekeji.com 软件安装…

​ 翻译 《The Old New Thing》

今天开始&#xff0c;为大家翻译微软优秀的技术专栏 The Old New Thing。 由微软高级工程师 Raymond Chen 撰写。该专栏起初是一个博客&#xff0c;后来也出版了同名书籍。专栏主要围绕 Windows 操作系统的开发和设计展开&#xff0c;涵盖了 Windows 平台的历史、技术细节、编程…

JMeter CSV 参数文件的使用方法

.在 JMeter 测试中&#xff0c;参数化是非常重要的&#xff0c;参数化允许我们模拟真实世界中的各种情况。本文我们将探讨如何在 JMeter 中使用 CSV 参数文件。 创建 CSV 文件 首先&#xff0c;我们需要创建一个逗号分隔的值&#xff08;CSV&#xff09;文件&#xff0c;其中…

http和socks5代理哪个好?

HTTP代理和SOCKS5代理各有其优缺点&#xff0c;但就隐蔽性而言&#xff0c;SOCKS5代理通常比HTTP代理更隐蔽。以下是它们的比较&#xff1a; HTTP代理&#xff1a; 透明性较高&#xff1a;HTTP代理在HTTP头中会透露原始客户端的IP地址&#xff0c;这使得它相对不太隐蔽。…

uni-app纵向步骤条

分享一下项目中自封装的步骤条&#xff0c;存个档~ 1. 话不多说&#xff0c;先看效果 2. 话还不多说&#xff0c;上代码 <template><!-- 获取一个数组&#xff0c;结构为[{nodeName:"流程发起"isAudit:falsetime:"2024-02-04 14:27:35"otherDat…

【Flink】Flink 处理函数之基本处理函数(一)

1. 处理函数介绍 流处理API&#xff0c;无论是基本的转换、聚合、还是复杂的窗口操作&#xff0c;都是基于DataStream进行转换的&#xff0c;所以统称为DataStreamAPI&#xff0c;这是Flink编程的核心。 但其实Flink为了更强大的表现力和易用性&#xff0c;Flink本身提供了多…

Qt程序可执行文件打包

目录 一、新建一个目录二、命令行2.1 添加临时变量2.2 打包命令 三、添加动态库四、普通 Qt 项目打包 Qml 项目打包 笔者写的python程序打包地址&#xff08;https://blog.csdn.net/qq_43700779/article/details/136994813&#xff09; 一、新建一个目录 新目录(例如test)用以…

Vue.js前端开发零基础教学(三)

目录 2.6 计算属性 2.7侦听器 2.8 样式绑定 2.8.1 绑定class属性 2.8.2 绑定style属性 2.9 阶段案例——学习计划表 2.6 计算属性 概念&#xff1a;Vue提供了计算属性来描述依赖响应式数据的复杂逻辑。 计算属性可以实时监听数据的变化&#xff0c;返回一个计算…

真假“长文本”,国产大模型混战

文&#xff5c;郝 鑫 Kimi有多火爆&#xff1f;凭一己之力搅乱A股和大模型圈。 Kimi概念股连日引爆资本市场&#xff0c;多个概念股随之涨停。在一片看好的态势中&#xff0c;谁都想来沾个边&#xff0c;据光锥智能不完全统计&#xff0c;目前&#xff0c;至少有包括读客…

【蓝桥杯知识点】浮点数二分(开n次方根再也不会超时啦!)

今天继续学习基础算法&#xff01;这篇文章介绍了二分的另一种应用——浮点数二分&#xff0c;可以用于开n次方根的计算&#xff0c;会使时间大大缩短&#xff01;我偷偷问过电脑编译器了&#xff0c;它说它喜欢优化过的算法哈哈哈哈~相信你也会喜欢的&#xff01; PS&#xff…

现代化应用部署工具-Docker

Docker 简介 什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上。 Docker部署的优势 通过使用Docker等容器技术&#xff0c;可以将应用程序及其依赖项…

构建品牌故事:Kompas.ai在叙事营销中的应用

引言 在数字化和全球化的浪潮中&#xff0c;品牌建设已经从单一的产品竞争演变为品牌故事的较量。叙事营销&#xff0c;作为一种通过讲述故事来传递品牌价值和理念的策略&#xff0c;已经成为连接品牌与消费者情感的桥梁。本文将深入探讨叙事营销的重要性&#xff0c;详细介绍K…

路由 (hash模式和history模式)

首先我们了解一下资源请求&#xff1a; 1.什么是资源 在浏览器需要某一个数据或文件进行解析或者浏览器在解析某个脚本的时候需要数据进行DOM渲染等工作&#xff0c;那么这个数据或文件就是浏览器的资源 2.资源怎么获取 浏览器的资源都必须通过资源请求的方式或从缓存中调出…

【Java程序设计】【C00371】基于(JavaWeb)Springboot的社区防疫物资申报系统(有论文)

TOC 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击卡片…

MapReduce配置和Yarn的集群部署

一、集群环境&#xff0c;还是如下三台服务器 192.168.32.101 node1192.168.32.102 node2192.168.32.103 node3 二、YARN架构 YARN&#xff0c;主从架构&#xff0c;有2个角色 主&#xff08;Master&#xff09;角色&#xff1a;ResourceManager从&#xff08;Slave&#x…