Java学习笔记——集合类学习

有一个经典的说法:算法+数据结构 = 程序,数据结构是计算机存储、组织数据的方式。说到数据存储,首先会想到的应该是数组,不过数组存储的数据是有固定长度的,而且Java中,对数组中的数据进行增加、删除操作比较麻烦(写到此处不能不给Python点赞)。

Java的标准类库提供了一套集合框架,给出了常用的数据结构实现。在Java5引入泛型后,几乎所有的集合API更新为支持泛型的版本,具有了编译器的类型安全检查。

小知识:所谓框架就是一个类库的集合。集合框架就是一个用来表示和操作集合统一的架构,包含了实现集合的接口与类。

集合框架的接口

主要分为两类:Collection和Map。以Collection根接口的一众实现保存的是单值数据,而以Map为根接口的一众实现保存的是键值(key-value)对数据。主要用到的有List、Set、Queue、Map,这四个接口的作用如下:

List:一个有序的集合,可以包含重复的元素,提供了按索引访问的方式。

Set:不能包含重复的元素。SortedSet是一个按照升序排列元素的Set。

Queue:定义了队列操作。队列是一种先进先出(FIFO)的数据结构。

Map:包含了key-value对。Map不能包含重复的key。SortedMap是一个按照升序排列key的Map。

1、实现List接口的两个实现:ArrayList和LinkedList

Collection类型的集合可以分为List、Set、Map三大类,要构建一个Collection接口对象,会选择三类接口中的某个实现来构建。例如ArrayList是一个常用的集合类,它实现了List接口,创建一个有序的集合。

import java.util.*;public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();for (int i=0;i<10;i++) {list.add(i);}for (Integer val : list) {System.out.print(val + "  ");}}
}

在向Collection类型的对象中添加元素时,可以使用add方法,如上代码向类型是ArrayList的list变量(Collection类型)增加10个int类型的数据。

Java语言中的ArrayList和LinkedList都是实现了List接口的集合类,用于存储元素的列表。尽管它们都提供了类似的功能,但在内部实现和使用特性上存在显著的区别。

  • 数据结构:ArrayList基于动态数组的数据结构,而LinkedList则是基于链表的数据结构。这导致了它们在不同操作上的效率差异。
  • 访问和修改元素:由于ArrayList是基于数组的,因此通过索引访问和修改元素(get和set操作)的效率非常高,时间复杂度为O(1)。而LinkedList则需要从头节点开始,遍历到指定的位置,所以访问特定元素的效率相对较低。
  • 插入和删除元素:对于在列表中间或尾部插入和删除元素的操作,LinkedList通常比ArrayList更高效。因为LinkedList只需要修改相关节点的指针,而ArrayList可能需要移动大量的元素来保持连续性。然而,在列表的开头插入或删除元素时,ArrayList的效率可能会稍高一些,因为它可以简单地移动内部数组的引用。
  • 空间占用:ArrayList在创建时会分配一个初始容量,并会随着元素的增加而自动扩容。这个扩容操作可能会导致额外的内存分配和复制操作。而LinkedList则不需要预留空间,它只在需要时分配新的节点。
  • 自由性:ArrayList的自由性相对较低,因为它需要预先设定一个固定大小的容量。而LinkedList则具有更高的自由性,因为它可以根据需要动态地增长和缩小。
  • 线程安全:ArrayList和LinkedList都不是线程安全的。如果在多线程环境下使用,可能需要额外的同步措施,或者使用线程安全的集合类,如Collections.synchronizedList()或CopyOnWriteArrayList。

ArrayList类,它实现了List接口,底层实现采用了数组来保存数据,可以把它看着是能够自动增长容量的数组(数组是固定的)。

在ArrayList中有一个数组和一个计数器,当向ArrayList中添加一个元素时,这个元素会放在计数器指定的数组索引位置上。当ArrayList对象中的数组无法保存更多元素时,它会创建一个比当前数组大一些的新数组,然后把当前的数组内容复制到新数组当中。

ArrayList初始的容量是全10,在程序中应该根据要保存的元素数量估算一个容量值,并在构造ArrayList对象时指定其容量,这样可以避免操作过程中频繁地发生数组的复制(虽然是自动完成),有利于提高程序的运行效率。

对于ArrayList类来说,它内部的数组大小(列表的容量)总是会比实际存储的元素数量要大一些,ArrayList类中有一个trimToSize方法,可以将列表的容量调整为列表的当前大小。

LinkedList也是List类型的一个集合类,与ArrayList不同的是,LinkedList底层采用了双向循环链表来保存元素。

除了实现List接口外,LinkedList还是先了Deque接口(双端队列,Queue的子接口),这使得LinkedList的方法要远远多于ArrayList。

总的来说,选择ArrayList还是LinkedList主要取决于使用场景。如果需要频繁地通过索引访问元素,或者预先知道列表的大致大小,那么ArrayList可能是一个更好的选择。而如果需要频繁地在列表中间插入或删除元素,或者列表的大小会动态变化,那么LinkedList可能更适合。

2、Map类型的集合

Map类型的集合使用键值对来保存对象,这意味着在保存对象时,需要同时提供两个对象,一个作为键(key),一个作为值(value)。

创建一个Map类型的对象,可以使用任何一个实现了Map接口的类。下面代码创建了一个HashMap对象:

Map<String, Integer> myMap = new HashMap<String, Integer>();

要向Map对象中添加数据可以使用put方法,它接受两个参数,即键和值。

myMap.put("age",19);

要想获取Map对象中的某个键对应的值可以使用get方法:

myMap.get("age“);   // 返回19

如果多次为同一个键(key)设置值,那么这个键对应的值是最后一次put时保存的值。

在Java中,有多种类实现了Map接口,每个类都有其独特的特点和适用场景。以下是一些主要的Map实现类及其区别:

  1. HashMap
    • 特点:基于哈希表实现,通过键的哈希值存储数据,提供了快速的插入和查找操作。
    • 适用场景:适用于存储大量的键值对,且对性能要求较高的情况。
    • 注意事项:HashMap不保证映射的顺序,即元素的迭代顺序可能与插入顺序不同。另外,HashMap不是线程安全的,如果在多线程环境下使用,需要额外的同步措施。
  2. LinkedHashMap
    • 特点:是HashMap的子类,它维护了一个双向链表来记录插入顺序或访问顺序。
    • 适用场景:当需要保持键值对的插入顺序或访问顺序时,可以使用LinkedHashMap。
    • 注意事项:由于维护了链表结构,相比HashMap,LinkedHashMap的插入和查找操作可能会稍慢一些。
  3. TreeMap
    • 特点:基于红黑树实现,可以保持键的自然顺序或自定义顺序。
    • 适用场景:当需要按键的顺序遍历键值对时,可以使用TreeMap。
    • 注意事项:TreeMap的插入和查找操作的时间复杂度为O(log n),比HashMap慢,但提供了有序的键值对存储。
  4. Hashtable
    • 特点:是古老的Map实现,与HashMap类似,但它是线程安全的。
    • 适用场景:在早期的Java版本中,当需要线程安全的Map时,会使用Hashtable。但现在,更推荐使用Collections.synchronizedMap()ConcurrentHashMap
    • 注意事项:Hashtable的键和值都不能为null,且其同步措施可能导致性能下降。
  5. ConcurrentHashMap
    • 特点:专为并发设计,支持高并发访问,提供了比Hashtable更高的吞吐量。
    • 适用场景:在多线程环境下,当需要线程安全的Map,并且要求较高的性能时,可以使用ConcurrentHashMap。
    • 注意事项:ConcurrentHashMap通过分段锁技术实现了线程安全,使得多个线程可以并发地修改Map的不同部分。

除了上述常见的Map实现类,Java还提供了其他的Map实现,如EnumMap(用于枚举类型的键)、IdentityHashMap(使用引用相等性而不是对象相等性)等,它们都有特定的使用场景和限制。在选择使用哪种Map实现时,应根据具体的需求和场景进行权衡。

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

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

相关文章

NOIP2011 数字反转 灰常经典的一道

[NOIP2011 普及组] 数字反转 - 洛谷https://www.luogu.com.cn/problem/P1307 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int Nsc.nextInt();int fanzhuanNumfanZhuan(N);System.out.print(fa…

LeetCode 面试题08.07.无重复字符串的排列组合

无重复字符串的排列组合。编写一种方法&#xff0c;计算某字符串的所有排列组合&#xff0c;字符串每个字符均不相同。 示例1: 输入&#xff1a;S “qwe” 输出&#xff1a;[“qwe”, “qew”, “wqe”, “weq”, “ewq”, “eqw”] 示例2: 输入&#xff1a;S “ab” 输出…

WSL使用

WSL使用 WSL安装和使用 Termianl和Ubuntu的安装 打开Hype-V虚拟化配置Microsoft Store中搜索Window Terminal并安装Microsoft Store中搜索Ubuntu, 选择安装Ubuntu 22.04.3 LTS版本打开Window Terminal选择Ubuntu标签栏, 进入命令行 中文输入法安装 查看是否安装了fcitx框架…

二分图

数据结构、算法总述&#xff1a;数据结构/算法 C/C-CSDN博客 二分图&#xff1a;节点由两个集合组成&#xff0c;且两个集合内部没有边的图。换言之&#xff0c;存在一种方案&#xff0c;将节点划分成满足以上性质的两个集合。 染色法 目的&#xff1a;验证给定的二分图是否可…

springboot3使用​自定义注解+Jackson优雅实现接口数据脱敏

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途 目录 写在前面 内容简介 实现思路 实现步骤 1.自定义脱敏注解 2.编写脱敏策略枚举类 3.编写JSON序列化实现 4.编写测…

日常刷题之77-组合

题目 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案 提示&#xff1a;假设 n5,k3 就是需要组合出来&#xff0c;长度3且内容数据是在[1,n]这个区间内的所有可能得组合 同时一个组合里面内个数字只能出现一次&#…

在linux中展示本月最后一个周五的日期

写法一 在Linux中&#xff0c;你可以使用date命令结合shell脚本来计算并展示本月最后一个周五的日期。以下是一个简单的bash脚本示例&#xff0c;用于实现这个功能&#xff1a; #!/bin/bash # 获取下个月的第一天 next_month$(date -d "next month" %Y-%m-01) …

亮数据代理IP轻松解决爬虫数据采集痛点

文章目录 一、爬虫数据采集痛点二、为什么使用代理IP可以解决&#xff1f;2.1 爬虫和代理IP的关系2.2 使用代理IP的好处 三、亮数据代理IP的优势3.1 IP种类丰富3.1.1 动态住宅代理IP3.1.2 静态住宅代理IP3.1.3 机房代理IP3.1.4 移动代理IP 3.2 高质量IP全球覆盖3.3 超级代理服务…

如何在Tomcat 9上部署前端和后端项目

在这篇指南中&#xff0c;我们将一步步介绍如何在Apache Tomcat 9服务器上部署一个前端项目&#xff08;我们的示例项目名为“dist”&#xff0c;常见于Vue.js、React等前端框架构建的产物&#xff09;和一个后端Java Web应用程序&#xff08;以WAR包形式&#xff09;。无论您是…

Java标签提高for循环运行效率,减少资源开销

一&#xff0c;Java标签提高for循环运行效率,减少资源开销 少说先看代码再讲解 List<Long> lefts new ArrayList<>(); List<Long> rights new ArrayList<>(); lefts.add(0L); lefts.add(1L); lefts.add(2L); lefts.add(3L); lefts.add(4L); lefts.…

修改Linux系统时间与网络同步

文章目录 1、安装ntpdate2、修改时区3、设置系统时间与网络时间同步4、将系统时间写入硬件时间 1、安装ntpdate # Red Hat和Cent OS系统 sudo yum install ntpdate # 乌班图 sudo apt-get install ntpdate2、修改时区 1&#xff09;运行tzselect tzselect2&#xff09;选择A…

Ubuntu篇——Ubuntu修改网卡优先级

背景&#xff1a;网线接了不能上互联网的局域网&#xff0c;WIFI连了可以上互联网的热点&#xff0c;但是发现上不了网&#xff0c;原因是网线的网卡优先级更高。 用指令临时修改网卡优先级的方法&#xff1a; 1.先看一下网卡基本信息 ip route show 显示内容如下&#xff…

通过socketpair()函数实现同一进程内部的进程间通信(IPC)

在某些情况下&#xff0c;我们可能需要将不同的进程之间进行数据传输或通信&#xff0c;而这些进程又在同一台计算机上运行。使用套接字&#xff08;socket&#xff09;是一种常用的IPC机制。通过创建一对文件描述符&#xff0c;可以在同一进程内模拟两个不同的套接字&#xff…

52、Qt/窗口、常用类、ui相关学习20240321

一、使用Qt 自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面。 要求&#xff1a; 1. 需要使用Ui界面文件进行界面设计 2. ui界面上的组件相关设置&#xff0c;通过代码实现 3. 需要添加适当的动图。 代码&#xff1a; #include "widget.h" #incl…

@Bean和@Component相似与区别

在Spring框架中&#xff0c;Bean和Component都是重要的注解&#xff0c;但它们之间存在一些明显的区别。 首先&#xff0c;它们的用途不同。Component是一个泛化的概念&#xff0c;用于标识一个普通的类&#xff0c;并将其声明为Spring组件。Spring可以扫描到配置了这个注解的…

两台不同账号同一区域阿里云服务器如何实现内网互通?

登录阿里云平台 [开通peer对等] 点击右上角的控制台&#xff0c;然后进行搜索专有网络VPC。 点击进入专有网络VPC界面操作步骤如下&#xff1a; &#xff08;1&#xff09;点击VPC对等连接&#xff0c;然后开通VPC对等连接后创建对等连接。 &#xff08;2&#xff09;在另…

霍夫变换找直线python代码以及从极坐标到笛卡尔坐标的转换

图像霍夫变换找直线 霍夫变换&#xff08;Hough Transform&#xff09;是图像分析中用于检测几何形状&#xff08;如直线、圆等&#xff09;的方法。最常用的是直线检测的霍夫变换&#xff0c;它可以从霍夫空间&#xff08;参数空间&#xff09;到笛卡尔空间&#xff08;图像空…

【计算机】——51单片机——持续更新

单片机是一种内部包含CPU、存储器和输入/输出接口等电路的集成电路&#xff08;IC芯片&#xff09; 单片机是单片微型计算机&#xff08;Single Chip Microcomputer&#xff09;的简称&#xff0c;用于控制领域&#xff0c;所以又称为微型控制器&#xff08;Microcontroller U…

【java基础】Java 的主要特性

Java语言是简单的 ● Java语言的语法与C语言和C语言很接近&#xff0c;使得大多数程序员很容易学习和使用。另一方面&#xff0c;Java丢弃了C中很少使用的、很难理解的、令人迷惑的那些特性&#xff0c;如操作符重载、多继承、自动的强制类型转换。特别地&#xff0c;Java语言不…

038—pandas 重采样线性插补

前言 在数据处理时&#xff0c;由于采集数据量有限&#xff0c;或者采集数据粒度过小&#xff0c;经常需要对数据重采样。在本例中&#xff0c;我们将实现一个类型超分辨率的操作。 思路&#xff1a; 首先将原始数据长度扩展为 3 倍&#xff0c;可以使用 loc[] 方法对索引扩…