Java核心技术 卷1-总结-12

news2025/4/4 17:47:11

Java核心技术 卷1-总结-12

  • 具体的集合
    • 链表
    • 数组列表

具体的集合

下表中除了以 Map结尾的类之外, 其他类都实现了 Collection 接口,而以 Map结尾的类实现了 Map 接口。

集合类型描述
ArrayList一种可以动态增长和缩减的索引序列
LinkedList一种可以在任何位置进行高效地插入和删除操作的有序序列
ArrayDeque一种用循环数组实现的双端队列
HashSet一种没有重复元素的无序集合
TreeSet一种有序集
EnumSet一种包含枚举类型值的集
LinkedHashSet一种可以记住元素插入次序的集
PriorityQueue一种允许高效删除最小元素的集合
HashMap一种存储键/值关联的数据结构
TreeMap一种键值有序排列的映射表
EnumMap一种键值属于枚举类型的映射表
LinkedHashMap一种可以记住键/值项添加次序的映射表
WeakHashMap一种其值无用武之地后可以被垃圾回收器回收的映射表
IdentityHashMap一种用==而不是用equals比较键值的映射表

在这里插入图片描述

链表

数组和数组列表(如 ArrayList)都有一个重大的缺陷。就是从数组的中间位置删除一个元素要付出很大的代价,其原因是数组中处于被删除元素之后的所有元素都要向数组的前端移动。在数组中间的位置上插入一个元素也会涉及到元素搬移。
在这里插入图片描述

链表(linked list)解决了这个问题。 数组在连续的存储位置上存放对象引用,链表却将每个对象存放在独立的结点中。每个结点还存放着序列中下一个结点的引用。在Java中,所有链表实际上都是双向链接的—即每个结点还存放着指向前驱结点的引用。
在这里插入图片描述
从链表中间删除一个元素只需要更新被删除元素附近的链接。
在这里插入图片描述

Java集合类库提供了一个类LinkedList,在下面的代码示例中,先添加3个元素,然后再将第2个元素删除:

List<String> staff = new LinkedList<>();//LinkedList implements List 
staff.add("Amy");
staff.add("Bob");
staff.add("Carl");
Iterator iter = staff.iterator();
String first = iter.next();//visit first element 
String second = iter.next();//visit second element 
iter.remove();// remove last visited element

链表与泛型集合之间有一个重要的区别。链表是一个有序集合(ordered collection)。 LinkedList.add方法将对象添加到链表的尾部。但是,常常需要将元素添加到链表的中间。由于迭代器是描述集合中位置的,所以这种依赖于位置的add方法将由迭代器负责。只有对自然有序的集合使用迭代器添加元素才有实际意义。例如,集合(set)类型中的元素完全无序。因此,在Iterator接口中就没有add方法。

相反地,集合类库提供了子接口ListIterator,其中包含 add方法:

interface ListIterator<E> extends Iterator<E> {
	void add(E element);
}

Collection.add不同,这个方法不返回boolean类型的值,它假定添加操作总会改变链表。另外,ListIterator接口有两个方法,可以用来反向遍历链表。

E previous()
boolean hasPrevious()

next方法一样,previous方法返回越过的对象。

LinkedList类的listiterator方法返回一个实现了ListIterator接口的迭代器对象。

ListIterator<String> iter = staff.listIterator();

Add方法在迭代器位置之前添加一个新对象。例如,下面的代码将越过链表中的第一个元素,并在第二个元素之前添加"Juliet"

List<String> staff = new LinkedList<>();
staff.add("Amy");
staff.add("Bob");
staff.add("Carl");
ListIterator<String> iter = staff.listIterator();
iter.next();// skip past first element 
iter.add("Juliet");

如果多次调用add方法,将按照提供的次序把元素添加到链表中。它们被依次添加到迭代器当前位置之前。

当用一个刚刚由Iterator方法返回,并且指向链表表头的迭代器调用add操作时,新添加的元素将变成列表的新表头。当迭代器越过链表的最后一个元素时(即hasNext返回false),添加的元素将变成列表的新表尾。如果链表有n个元素,有n+1个位置可以添加新元素。

LinkedListset方法用一个新元素取代调用nextprevious方法返回的上一个元素。例如,下面的代码将用一个新值取代链表的第一个元素:

ListIterator<String> iter = list.listIterator();
String oldValue = iter.next();// returns first element 
iter.set(newValue);// sets first element to newValue

如果在某个迭代器修改集合时,另一个迭代器对其进行遍历,一定会出现混乱的状况。例如,一个迭代器指向另一个迭代器刚刚删除的元素前面,现在这个迭代器就是无效的,并且不应该再使用。 链表迭代器的设计使它能够检测到这种修改。如果迭代器发现它的集合被另一个迭代器修改了,或是被该集合自身的方法修改了,就会抛出一个ConcurrentModificationException异常。例如下面这段代码:

List<String> list = . . . ;
ListIterator<String> iter1= list.listIterator();
ListIterator<String> iter2= list.listIterator();
iter1.next();
iter1.remove();
iter2.next();// throws ConcurrentModi ficationException

iter2检测出这个链表被从外部修改了,所以对iter2.next的调用抛出了一个ConcurrentModificationException异常。

为了避免发生并发修改的异常,需要遵循下述规则:可以根据需要给容器附加许多的迭代器,但是这些迭代器只能读取列表。另外,再单独附加一个既能读又能写的迭代器。

有一种简单的方法可以检测到并发修改的问题。集合可以跟踪改写操作(诸如添加或删除元素)的次数。每个迭代器都维护一个独立的计数值。在每个迭代器方法的开始处检查自己改写操作的计数值是否与集合的改写操作计数值一致。如果不一致,抛出一个ConcurrentModificationException异常。

Collection接口中声明了许多用于对链表操作的有用方法。其中大部分方法都是在LinkedList类的超类AbstractCollection中实现的。例如,toString方法调用了所有元素的toString,并产生了一个很长的格式为[A,B,C]的字符串。可以使用contains方法检测某个元素是否出现在链表中。例如,如果链表中包含一个等于“Harry”的字符串,调用staff.contains(“Harry”)后将会返回true

链表不支持快速地随机访问。如果要查看链表中第n个元素,就必须从头开始,越过n-1个元素。没有捷径可走。 鉴于这个原因,在程序需要采用整数索引访问元素时,通常不选用链表。尽管如此,LinkedList类还是提供了一个用来访问某个特定元素的get方法:

LinkedList<String> list = ...;
String obj = list.get(n);

注意:get方法做了微小的优化:如果索引大于size()/2就从列表尾端开始搜索元素。

列表迭代器接口还有一个方法,可以告之当前位置的索引。 实际上,由于Java迭代器指向两个元素之间的位置,所以可以同时产生两个索引:nextIndex方法返回下一次调用next方法时返回元素的整数索引;previousIndex方法返回下一次调用previous方法时返回元素的整数索引。这个索引只比 nextlndex返回的索引值小1。这两个方法的效率非常高,这是因为迭代器保持着当前位置的计数值。

使用链表的唯一理由是尽可能地减少在列表中间插入或删除元素所付出的代价。如果列表只有少数几个元素,就完全可以使用ArrayList 如果需要对集合进行随机访问,就使用数组或ArrayList,而不要使用链表。

数组列表

List 接口用于描述一个有序集合,并且集合中每个元素的位置十分重要。 有两种访问元素的协议:一种是用迭代器,另一种是用getset方法随机地访问每个元素。后者不适用于链表,但对数组却很有用。集合类库提供了ArrayList类,这个类也实现了List接口。ArrayList封装了一个动态再分配的对象数组。

在需要动态数组时,可能会使用Vector类。因为Vector类的所有方法都是同步的。但是,如果由一个线程访问Vector,代码要在同步操作上耗费大量的时间。ArrayList方法不是同步的,因此,在不需要同步时使用ArrayList,而不要使用Vector

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

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

相关文章

为视频直播网站开发选择最佳技术

在今天的数字时代&#xff0c;随着人们越来越多地倾向于观看在线视频&#xff0c;视频直播网站开发已经成为了一项非常有前途的技术。无论是为了提供娱乐、教育还是商业目的&#xff0c;视频直播网站开发都是一个非常重要的领域。 在视频直播网站开发中&#xff0c;你需要考虑…

使用Process Monitor探测日志文件是C++程序哪个模块生成的

目录 1、问题描述 2、使用Process Monitor监测目标文件是哪个模块生成的思路说明 3、操作Process Monitor监测日志文件是哪个模块生成的 4、通过screenctach.dll库的时间戳&#xff0c;找到其pdb文件&#xff0c;然后去查看详细的函数调用堆栈 5、最后 VC常用功能开发汇总…

春秋云境:CVE-2022-25099(文件上传造成RCE)

目录 一、题目 二、burp上传执行木马 一、题目 介绍&#xff1a; WBCE CMS v1.5.2 /language/install.php 文件存在漏洞&#xff0c;攻击者可精心构造文件上传造成RCE 进入题目&#xff1a; 网站正在建设中。。。 直接访问/admin吧&#xff1a; admin:123456 成功进入&…

css案例:小黄人案例

css案例&#xff1a;小黄人案例 先看效果图 眼睛和嘴巴有做动画的&#xff0c;但是我懒得上传gif了。 3. 源码 html <!DOCTYPE html> <html lang"en"> <head><meta charset"utf-8"><style>.contain {width: 400px;height:…

贪心-合并果子(经典Huffman树)

题意 在一个果园里&#xff0c;达达已经将所有的果子打了下来&#xff0c;而且按果子的不同种类分成了不同的堆。 达达决定把所有的果子合成一堆。 每一次合并&#xff0c;达达可以把两堆果子合并到一起&#xff0c;消耗的体力等于两堆果子的重量之和。 可以看出&#xff0c;所…

Linux驱动开发:uboot启动流程详解

前言&#xff1a;uboot作为Linux驱动开发的 “三巨头” 之一&#xff0c;绝对是一座绕不开的大山。当然&#xff0c;即使不去细致了解uboot启动流程依旧不影响开发者对uboot的简单移植。但秉持着知其然知其所以然的学习态度&#xff0c;作者将给读者朋友细致化的过一遍uboot启动…

如何用ChatGPT举办活动,人类与AI的一次深度对谈

刚刚&#xff0c;Mixlab今年首次线下联合举办的活动开启了&#xff0c;活动不仅分享了AIGC对体验设计的新要求、内容产业的发展研判、用于模拟仿真的生成式智能体&#xff0c;还演示了AI如何深度整合到一场活动之中。 1/ 数字人出场介绍Mixlab 是如何实现的呢&#xff1f;无限…

[Net]SSE消息推送简介

文章目录 SSE网络协议客户端服务端事件 SSE示例客户端服务端 SSE&#xff08;Server-Sent Events&#xff09;是一种服务端到客户端&#xff08;浏览器&#xff09;的单向消息推送方式。 SSE网络协议 SSE是基于HTTP协议的&#xff0c;客户端向服务端发起一个请求&#xff0c;建…

Android 9.0 系统设置显示主菜单添加屏幕旋转菜单实现旋转屏幕功能

1.前言 在android9.0的系统rom定制化开发中,在对系统设置进行定制开发中,有产品需求要求增加旋转屏幕功能的菜单,就是在点击旋转屏幕菜单后弹窗显示旋转0度,旋转 90度,旋转180度,旋转270度针对不同分辨率的无重力感应的大屏设备的屏幕旋转功能的实现,接下来就来分析实现…

以太网PLC无线WIFI跨网段通讯和Modbus仪表数据采集

产品介绍 产品型号&#xff1a;NET50-NAT-W4 使用范围&#xff1a;用于以太网PLC的跨网段无线通讯和仪表的数据采集 产品介绍 工业通讯桥接器&#xff08;NET50-NAT-W4&#xff09;用于以太网PLC的通讯扩展&#xff0c;以太网跨网段通讯和Modbus仪表的数据采集&#xff0c;上…

2023年制造业产品经理考NPDP有什么用?

产品经理国际资格认证NPDP是新产品开发方面的认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年&#xff0c;是…

谈一谈django应用实践

python 的 web 框架非常多,比较出名的有 django, flask, tornado。django 作为一个老牌框架,无论是文档还是代码质量都非常高,另外他自带的 admin 后台和一些有用的 app,如果你的需求是做 cms 之类的 web 应用的话,基本上不用开发多少代码就能出一个成品。不过很多新手可能…

2023-04-23 学习记录--C/C++-函数

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 【一】、调用有参函数 ⭐️ 有参函数&#xff1a;调用函数时&#xff0c;需要传对应参数。 一、实现步骤 &#x1f338; 实现步骤…

Adobe国际认证证书,深化设计师个人优势!

Adobe国际认证又称为Adobe认证(英文:Adobe Certified Professional)是Adobe公司CEO签发的权威国际认证体系,旨在为用户提供Adobe软件的专业认证。 该体系基于Adobe核心技术及岗位实际应用操作能力的测评体系得到国际ISTE协会的认可&#xff0c;并在全球 148 个国家推广&#xf…

mybatis分页插件的详细理解和使用

mybatis分页插件的基本理解和使用 为什么要使用mybatis分页插件&#xff1f; 分页是一种将所有数据分段展示给用户的技术。用户每次看到的不是全部数据&#xff0c;而是其中一部分&#xff0c;如果在其中没有找到自己想要的内容&#xff0c;用户可以通过制定页码或者是翻页的…

头歌c语言实训项目-综合案例课外练习:学生成绩管理系统

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 第1关&#xff1a;学生成绩管理系统 题目&#xff1a; 代码思路&#xff1a; 代码表示&#xff1a; 如…

【Git】git使用

vitevue3部署静态文件到github 1. 新建仓库 新建仓库 仓库名称: 必须是 [你的git用户名]或[仓库名称] .github.io&#xff0c;例如你的用户名是YunZhonJun&#xff0c;统一为小写&#xff0c;如↓ 例1 用户名.github.io yunzhonjun.github.io 例2 仓库名称.github.io colors…

【动力节点】Springsecurity14-18章JWT+Spring Security+redis+mysql 实现认证

15 SpringSecurity 集成thymeleaf 此项目是在springsecurity-12-database-authorization-method 的基础上进行 复制springsecurity-12-database-authorization-method 并重命名为springsecurity-13-thymeleaf 15.1 添加thymeleaf依赖 | org.springframework.boot spring-…

根据vue2数组响应式实现原理找到了一个待优化点

最近学习了相关知识 写出了 vue2数据响应式原理(5) 通过重写函数实现数组响应式监听但也在这里 我发现 数组响应式 一个是通过for遍历监听已有属性 还有就是重写会改变数组的几个内置函数来监听 但 如果 元素之前没有 且 我们不适用这些内置函数去修改呢&#xff1f; 我们创建…