JavaSE之集合篇

news2025/1/16 1:08:04

文章目录

  • 前言
  • 一、集合概述
    • 集合继承结构图
  • 二、Collection接口中常用方法
    • 2.1Collection中存放什么元素?
    • 2.2常用方法
    • 2.3迭代器
  • 三、List接口中常用的方法
  • 四、ArrayList初始化容量及扩容
  • 五、Vector
  • 六、Map接口常用方法
  • 七、Properties


前言

由于在刷题过程中,经常遇到map的使用,顺便一起回忆一波


一、集合概述

数组其实就是一个集合,
集合不能直接存储基本数据类型,另外集合也不能直接存储Java对象,集合中存储的都是Java对象的内存地址。(或者说集合中存储的是引用)

在Java中每一个不同的集合,底层会对应不同的数据结构。往不同的集合中存储数据元素,等于将数据放到了不同的数据结构当中。

集合在Java JDK中哪个包下?
java.util.* 所有的集合类和集合接口都在java.util包下

集合继承结构图

在Java中集合分为两大类:

  • 一类是单个方式存储元素:这一类集合中超级父接口 java.util.Collection
    在这里插入图片描述

Collection下有主要的两大类:List和Set【常用的】
list集合的特点:有序可重复,存储的元素有下标【有序实际上是说存进去是这个顺序,取出来还是这个顺序,不是按照大小顺序排序】,有序是因为list集合都有下标,下标从0开始 以1递增

ArrayList、LinkedList、Vector【常用的】
ArrayList底层采用了数组这种数据结构【非线程安全的】
LinkedList底层采用了双向链表数据结构
Vector底层采用了数组这种数据结构【线程安全的,所有的方法都有synchronized关键词修饰,但是效率较低。现在保证线程安全有别的方案,因此使用较少】

Set集合存储元素的特点:无序,表示存进去是这个顺序,取出来就不一定是这个顺序了,不可重复,没有下标。

HashSet:实际上HashSet在new的时候底层实际创建了一个HashMap集合。向HashSet集合中存储元素实际上是存储到HashMap集合中了。HashMap集合是一个哈希表数据结构
TreeSet的父接口:SortedSet 【SortedSet的父接口Set】,TreeSet集合底层实际上是TreeMap,new TreeSet集合实际上是new了一个TreeMap集合,TreeMap底层采用了二叉树的数据结构

  • 一类是以键值对的方式存储元素:java.util.Map

1、Map集合和Collection没有关系
2、Map集合以key和value的方式存储
3、key和value豆豆hi存储Java对象的内存地址
4、所有map集合的key都是无序不可重复的
map集合的key和set集合存储元素特点相同【给set集合添加元素实际上是加到了map集合的key部分】

HashMap:【非线程安全的】底层是哈希表数据结构,无序不可重复
HashTable:【线程安全的】底层是哈希表数据结构,效率较低,现在使用较少
Properties【属性类】继承了HashTable,线程安全的
SortedMap【接口】无需不可重复,另外放在SortedMap key部分的元素会自动按照大小排序,称为可排序的集合---->TreeMap是它的实现类,TreeMap集合底层的数据结构是一个二叉树

总结(所有的实现类):
ArrayList:底层是数组
LinkedList:底层是双向链表
Vector:底层是数组,线程安全的,效率较低,使用较少。
HashSet:底层是HashMap,放到HashSet集合中的元素等同于放到HashMap集合key部分了
TreeSet:底层是TreeMap,放到TreeSet集合中的元素等同于放到TreeMap集合key部分了
HashMap:底层是哈希表
Hashtable:底层是哈希表,线程安全的,效率较低,使用较少
Properties:线程安全的,key和value只能存储字符串
TreeMap:底层是二叉树,TreeMap集合的key可以自动按照大小排序

List集合存储元素的特点:有序(有下标)可重复(存进去的元素和取出的元素顺序相同)
Set(Map)集合存储元素的特点:无序不可重复
SortedSet(SortedMap)集合存储元素的特点:无序不可重复,但是SortedSet集合中的元素的可排序(可以按照大小顺序排列)的。

二、Collection接口中常用方法

2.1Collection中存放什么元素?

没有使用“泛型”之前,Collection中可以存放Object的所有子类型
使用泛型之后,Collection中只能存储某个具体类型

2.2常用方法

创建一个集合对象
【多态,父类型引用指向子类型对象】

Collection<> c = new ArrayList<>();

向集合中添加元素

c.add(1200)//自动装箱 实际上是放进去了一个对象的内存地址。
c.add(3.14)
c.add("hello")
c.add(new Object());
c.add(true)

获取集合中的元素个数

c.size();//5

清空集合

c.clear();

判断集中中是否包含某个元素o

注意:在没有重写equals之前 会比较内存地址 结果是false

底层调用的是 equals() 方法【比较的是内容不是内存地址】

存放在集合中的类型,一定要重写equals方法

c.contains("hello")
public static void main(){
	Collection c = new ArrayList();
	User u1 = new User("jack");
	c.add(u1);
	User u2 = new USer("jack");
	//注意:在没有重写equals之前 会比较内存地址 结果是false
	c.contains(u2);
}

Class User{
	private String name;
	public User(){};
	public User(String name){
		this.name = name;
	}
}

删除集合中某个元素
remove底层也调用了equals方法

c.remove()
String s1 = "hello";
Strign s2 = "hello";
c.add(s1);
c.add(s2);
c.remove(s2);//会不会把s1也删除掉? --->会

判断集合是否为空

c.isEmpty();

把集合转化为数组

c.toArray();

2.3迭代器

迭代器是所有Collection通用的一种方式,在Map集合中不能用,在所有的Collection以及子类中使用

一定要注意:集合结构只要发生改变【添加一个元素或者删除元素】迭代器都必须重新获取,如果没有重新获取迭代器就会出现异常,根本原因在于:集合中元素删除了,但是没有更新迭代器
迭代器去删除时,会自动更新迭代器,并且更新集合 【删除集合中元素】

	Collection c = new ArrayList();
	c.add("hello");
	c.add("bwy");
	c.add(100);
	c.add(new Object());
	Iterator it = c.iterator();
	while(it.hasNext()){
		Object o = it.next();
	}

三、List接口中常用的方法

list:有序可重复

1、创建list类型的集合

List list = new ArrayList();

2、添加元素

默认都是向集合末尾添加元素

list.add("A"); //默认都是向集合末尾添加元素
list.add(1,"bwy") //在指定位置插入指定元素 使用不多,效率比较低

3、根据下标获取元素
因为有下标,因此list集合有自己比较特殊的遍历方式

Object 0 = list.get(0);
//遍历方式
for(int i=0;i<list.size();i++){
	Object o = list.get(i); 
}

4、获取指定对象第一次以及最后一次出现处的索引

int index1 = list.indexOf("A");
int index2 = list.lastIndexOf("A");

5、根据下标删除元素

list.remove(0);

6、修改指定位置元素

list.set(2,"soft");

四、ArrayList初始化容量及扩容

ArrayList初始化容量是10;
list.size()是10还是0呢?----->0 集合中的size()方法是获取当前集合中元素的个数
容量和size两回事
ArrayList集合底层是一个Object[]数组

在这里插入图片描述

五、Vector

底层是一个数组,初始容量10
将不安全的ArrayList变为线程安全的:

List list = new ArrayList();
Collections.synchronizedList(list);

六、Map接口常用方法

1、map和Collection没有继承关系
2、Map集合以key和value的方式存储数据
key和value都是引用数据类型
key和value都是存储对象的内存地址

void clear();清空Map集合
boolean containsKey(Object key); 判断Map中是否包含某个key
boolean containsValue(Object value);判断Map中是否包含某个value
V get(Object key); 通过key获取value
boolean isEmpty(); 判断Map集合中元素个数是否为0
V put(K key,V value); 向Map集合总添加键值对
V remove(Object key) 通过key删除键值对
int size(); 获取Map集合中键值对的个数
Collection< V> values(); 获取Map集合中所有的value,返回一个Collection
Set<Map.Entry<K,V>> entrySet();将Map集合转换为set集合

Map集合的遍历【重要】

  • 方式一:获取所有的key,通过遍历key,来获取所有的value
Map<Integer,String> map = new HashMap<>();
        map.put(1,"abc");
        map.put(2,"bwy");
        map.put(3,"ccc");
        //遍历map集合
        //获取所有的key 所有的key是一个set集合
        Set<Integer> set = map.keySet();
        //遍历key
        //方法1:迭代器
        Iterator it = set.iterator();
        while(it.hasNext()){
            Integer k = (Integer) it.next();
            String value = map.get(k);
            System.out.println(k+"="+value);
        }
        //方法2:foreach
        for(Integer key:set){
            String value = map.get(key);
            System.out.println(key+"="+value);
        }

在这里插入图片描述

  • 方式二:Set<Map.Entry<K,V>> entrySet();【将map集合全部转换为set集合】
    在这里插入图片描述
 Map<Integer,String> map = new HashMap<>();
        map.put(1,"abc");
        map.put(2,"bwy");
        map.put(3,"abc");
        //遍历map集合
        //Set<Map.Entry<Integer, String>> set = map.entrySet();
        Set<Map.Entry<Integer, String>> set = map.entrySet();
        //foreach遍历
        for(Map.Entry<Integer,String> m : set){
            int k = m.getKey();
            String value = m.getValue();
            System.out.println("foreach遍历"+k+"="+value);
        }
        //迭代器遍历
        Iterator<Map.Entry<Integer, String>> it = set.iterator();
        while(it.hasNext()){
            Map.Entry<Integer, String> next = it.next();
            int k = next.getKey();
            String value = next.getValue();
            System.out.println("迭代器遍历"+k+"="+value);
        }

在这里插入图片描述

map.put(k,v)实现原理
第一步:先将k,v封装到Node对象当中
第二部:底层会调用hashCode()方法得出hash值,然后通过哈希函数,将哈希值转换为数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上了,如果下标对应的位置上有链表,此时会拿着k和链表上每一个结点中的k进行equals,如果所有的equals方法都是返回false,那么这个新节点将会被添加到链表的末尾,如果有其中一个返回true,那么这个节点的value将会被覆盖

v = map.get(k)实现原理
先调用k的hashCode()方法得出的哈希值,通过哈希算法转换成数组下标,通过数组下标快速定位到某个位置上,如果这个位置上什么也没有,返回null,如果这个节点上有单向链表,那么会拿着参数k和单向链表上每个结点的k进行equals,如果所有的equals方法都返回false,那么get方法返回null,只要其中一个结点的k和参数k equals的时候返回true,那么此时这个结点value就是我们要找的value,get方法最终返回这个value

为什么哈希表的随机增删,以及查询效率都很高
1、增删是在链表上完成的
2、查询不需要都扫描,只需要部分扫描

重点
HashMap集合的key会先后调用两个方法,一个方法是hashCode(),一个方法是equals(),那么这两个方法都需要重写。

在JDK8之后,如果哈希表单向链表中元素超过8个,单向链表这种数据结构就会变成红黑树数据结构,当红黑树上的节点小于6会重新变成单向链表

HashMap和Hashtable的区别
HashMap集合key部分允许为空,且只允许有一个。putVal()中有对null的处理
在这里插入图片描述
Hasttable集合key部分不允许为空,value也不允许为空。【空指针异常】

七、Properties

创建一个Properties对象

Properties pro = new Properties()

存:

pro.setProperty("username","root");
pro.setProperty("password","123456");

取:

pro.getPropertry(username);//root
pro.getPropertry(password);//123456

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

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

相关文章

大型三甲医院云HIS系统源码 强大的电子病历+完整文档

医院HIS系统源码云HIS系统&#xff1a;SaaS运维平台多医院入驻强大的电子病历完整文档 有源码&#xff0c;有演示 一、系统概述 采用主流成熟技术&#xff0c;软件结构简洁、代码规范易阅读&#xff0c;SaaS应用&#xff0c;全浏览器访问前后端分离&#xff0c;多服务协同&am…

使用AppSmith(PagePlug )低代码平台快速构建小程序应用实践

文章目录一、入门&#xff08;一&#xff09;介绍&#xff08;二&#xff09;功能特性&#xff08;三&#xff09;体验一下&#xff08;四&#xff09;参考教程二、使用Appsmith构建商城微信小程序&#xff08;一&#xff09;说明&#xff08;二&#xff09;应用配置&#xff0…

安卓逆向_5 --- jeb 和 AndroidStudio 动态调试 smali

Jeb 工具的使用 &#xff1a;https://www.52pojie.cn/forum.php?modviewthread&tid742250&#xff1a;https://zhuanlan.zhihu.com/p/302856081动态调试 smali 有两种方法&#xff1a; Jeb 调试AndroidStudio smalidea 插件动态调试。1、Jeb 动态调试 smali ​JEB是一个…

LeetCode 236.二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它自己的祖…

Modbus协议初探(C#实现)

由于作者水平有限&#xff0c;如有写得不对得地方请指正 趁着今天休息&#xff0c;就折腾一下Modbus协议&#xff0c;之前零零散散的看过几篇博客&#xff0c;听说搞上位机开发的要会这个协议&#xff0c;虽然我不是搞上位机开发的&#xff0c;但个人对这个比较感兴趣。按照我个…

开发一个看番app[樱花动漫移动端app]

使用react-native开发&#xff0c;功能&#xff1a; 支持看番支持历史记录浏览支持追番 项目地址: https://github.com/HGGshiwo/Sakura 界面&#xff1a; 首页分类用户界面播放界面历史记录搜索界面全部动漫追番

OpenAI Whisper and ChatGPT 语音助手

OpenAI Whisper and ChatGPT ASR Gradio Web UI一 环境准备1.1 python1.2 windows二 导入所需要的包三 加载模型四 定义openai和whisper接口五 生成Gradio Web UI麦克风输入&#xff0c;展示三种结果输入ASR结果输出文本输出TTS结果 一 环境准备 1.1 python gradio3.19.1 gTT…

ubuntu 如何搭建git远程仓库

ubuntu 安装git sudo apt-get install git配置用户名和邮箱 git config --global user.name “xxx” git config --global user.email “邮箱地址”关于远程仓库 Git是分布式版本控制系统&#xff0c;同一个Git仓库&#xff0c;可以分布到不同的机器上。这就需要一台电脑充当…

打印名片-课后程序(Python程序开发案例教程-黑马程序员编著-第一章-课后作业)

实例2&#xff1a;打印名片 名片是标示姓名及其所属组织、公司单位和联系方法的纸片&#xff0c;也是新朋友互相认识、自我介绍的快速有效的方法。本实例要求编写程序&#xff0c;模拟输出效果如图1所示的名片。 图1 名片样式 实例目标 掌握print()函数的用法 实例分析 名片…

【办公类-19-01-02】办公中的思考——Python,统计教职工的姓名中那些字最多?

背景需求&#xff1a;上一篇计算了教职工的姓氏谁最多&#xff0c;col[0]]这一篇统计教职工的&#xff08;姓氏名字&#xff09;里面哪些字出现最多。材料准备&#xff1a;1、下载所有员工名单写代码。py 包含”姓氏名字“的重字率统计from pandas import DataFrame, Series im…

DevOps践行

DevOps 是开发 (Dev) 和运营 (Ops) 的复合词&#xff0c;它将人、流程和技术结合起来&#xff0c;不断地为客户提供价值。 DevOps 对团队意味着什么&#xff1f; DevOps 使以前孤立的角色&#xff08;开发、IT 运营、质量工程和安全&#xff09;可以协调和协作&#xff0c;以生…

二次封装element plus (el-select-v2远程搜索组件)

根据项目需求,需要给每个对应的搜索字段进行 远程搜索项目中有跟多地方都需要使用,所以进行二次封装会很方便.创建一个ElSelectV2文件夹> index.vue<template><div><el-select-v2v-model"valueName"filterableremote:remote-method"remoteMet…

tomcat启动流程以及线程池配置

一、启动流程 二、 线程池配置 Tomcat的maxConnections、maxThreads、acceptCount三大配置&#xff0c;分别表示最大连接数&#xff0c;最大线程数、最大的等待数&#xff0c;可以通过application.yml配置文件来改变这个三个值&#xff0c;一个标准的示例如下&#xff1a; se…

Linq的底层原理探讨

前言有一篇文章ABP-引入SqlSugar很多人都在催促我&#xff0c;出下一章因为工作忙一直没写。现在开第二节课Linq的底层原理探讨。一起探讨完&#xff0c;看看有没有引起SqlSugar的新思路。这文章叫linq的底层原理。从哪里开始说呢&#xff1f;Linq To SQL、Linq To Objects、Li…

计算机的学习路线

本文是介绍如何成为一个Geek&#xff0c;一个真正的计算机高手。 适合有成为IT领域技术大牛的人参考。 写给大一新生和所有向深耕IT领域的人&#xff0c;避免走一些弯路。 第一门入门的必备功课-语法与算法 什么是计算机&#xff1f; 用来做运算的机器 电子计算机在运算方面…

[1.3_1]计算机系统概述——操作系统的运行机制

文章目录第一章 计算机系统概述操作系统的运行机制前提知识&#xff1a;程序是如何运行的内核程序与应用程序特权指令与非特权指令内核态与用户态小结第一章 计算机系统概述 操作系统的运行机制 操作系统的运行机制&#xff0c;也就是操作系统在计算机上是怎样运行的问题。 操…

Go语言的条件控制语句及循环语句的学习笔记

一、Go的条件控制语句 Go 语言提供了以下几种条件判断语句&#xff1a; 语句描述if 语句if 语句 由一个布尔表达式后紧跟一个或多个语句组成。if…else 语句if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。if 嵌套语句你可以在 if 或…

C++概览:工具链、基础知识、进阶及总结

本篇写给C初学者&#xff0c;作为概览&#xff0c;文中仅包含各方面基础知识&#xff0c;无深入分析。 C基础概念简介 C编译过程示意图 关键词&#xff1a;源文件、预编译、编译、汇编、链接 C工具链总结 cmake项目工程文件是一种中介工程文件&#xff0c;可以转化成其他…

Python+Qt指纹录入识别考勤系统

PythonQt指纹录入识别考勤系统如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01;前言这篇博客针对<<PythonQt指纹录入识别考勤系统>>编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易读。 学…

如何在 OpenEuler 系统中安装 Docker

Docker 是一种流行的开源容器化平台&#xff0c;它能够将应用程序与其依赖项打包成可移植的容器&#xff0c;从而简化了应用程序的部署和管理。本文将介绍在 OpenEuler 系统中安装 Docker 并使用 Docker 容器控制 5G 模块的具体步骤。 安装 Docker 安装 Docker 的具体步骤如下…