当前位置: 首页 > news >正文

Typescript高级: 对泛型和多态的应用, 实现Java中的ArrayList和LinkedList

ArrayList


1 ) 概述

  • 在Java中,ArrayList是一个非常常用且强大的数据结构,它提供了动态数组的功能
  • 能够方便地添加、删除和访问元素。在TypeScript中,虽然并没有内置的ArrayList类型
  • 但我们可以通过类与接口来模拟实现ArrayList的功能

2 )实现

interface List<T> {size: number;add(item: T): void;get(index: number): T | undefined;remove(item: T): boolean;show(): void;
}class ArrayList<T> implements List<T> {public array: T[];private index: number = 0;public size: number = 0;constructor() {this.array = [];}// 添加元素,重载 add 方法add(item: T): void;add(item: any): void;add(item: number): void;add(item: string): void;add(item: any): void {this.array.push(item);this.size++;this.index = this.array.length; // 更新索引为数组最后一个元素的索引+1}// 获取元素get(index: number): T | undefined {return this.array[index];}// 删除元素,重载 remove 方法remove(item: T): boolean;remove(item: any): boolean;remove(item: number): boolean;remove(item: string): boolean;remove(item: any): boolean {const index = this.array.indexOf(item);if (index !== -1) {this.array.splice(index, 1);this.size--;return true;}return false;}// 显示全部数据show(): void {console.log(this.array);}// 更新元素,这里并没有在接口中定义,作为额外功能添加update(index: number, newValue: T): boolean {if (index >= 0 && index < this.size) {this.array[index] = newValue;return true;}return false;}
}const arrayList = new ArrayList<string>();// 添加元素
arrayList.add("Hello");
arrayList.add("World");
arrayList.add(42); // 这将不会报错,因为 TypeScript 中的泛型在运行时会被擦除,并且 add 方法被重载以接受 any 类型// 显示元素
arrayList.show(); // 输出: [ 'Hello', 'World', 42 ]// 获取元素
console.log(arrayList.get(0)); // 输出: Hello// 更新元素
arrayList.update(1, "TypeScript");
arrayList.show(); // 输出: [ 'Hello', 'TypeScript', 42 ]// 删除元素
console.log(arrayList.remove("TypeScript")); // 输出: true
arrayList.show(); // 输出: [ 'Hello', 42 ]// 获取数组大小
console.log(arrayList.size); // 输出: 2

3 )说明

  • 在基础List类型中,我们定义了如下方法和属性

    • add(item: T): 添加一个元素到ArrayList中
    • get(index: number): 根据索引获取元素
    • size: 存储ArrayList中元素的数量
    • remove(item: T): 删除一个元素
    • show(): 显示ArrayList中的所有元素
  • ArrayList 这个类继承List接口,并实现其所有的方法

  • 这里面实现了方法的多态和泛型

    • 1 )多态(Polymorphism)的主要优势在于提高了代码的可维护性和扩展性
    • 通过使用多态,我们可以编写更加灵活和可重用的代码
    • 因为我们可以定义通用的接口或方法,而不必关心具体实现细节
    • 2 ) 泛型(Generics)是TypeScript中一种强大的工具
    • 它允许我们在不丢失类型信息的前提下,编写可重用的组件
    • 这些组件可以与多种不同的类型一起工作,而不仅仅是一个类型
    • 泛型的主要作用是提供类型安全,同时确保代码的可复用性
    • 通过使用泛型,我们可以在保证类型安全的同时
    • 让函数与多种类型一起工作
  • 总结来说

    • 泛型和多态是TypeScript中两个强大的特性
    • 它们分别通过提供类型安全和允许统一操作不同数据类型来增强代码的可复用性和灵活性
    • 在实际开发中,结合使用泛型和多态可以帮助我们编写更加健壮、可维护和可扩展的代码

LinkedList


1 ) 概述

  • 在TypeScript中,实现一个双向链表(Doubly Linked List)相比于ArrayList会更加复杂
  • 因为我们需要维护每个节点的两个指针:一个指向前一个节点,另一个指向下一个节点
  • 同时,我们还要确保List接口的所有方法都能得到正确实现
  • 在数据结构中,链表是一种动态分配内存空间的线性数据结构
  • 由一系列的节点组成,每个节点通常包含两部分:
    • 一部分用于存储数据
    • 另一部分用于存储指向下一个节点的指针
  • 而双向链表,顾名思义,就是每个节点不仅包含指向下一个节点的指针
  • 还包含指向前一个节点的指针, 这使得双向链表在插入和删除节点时更为灵活

2 )实现

interface List<T> {add(element: T): void;get(index: number): T | undefined;size: number;remove(element: T): boolean;
}class N<T> {value: T;next: N<T> | null;prev: N<T> | null;constructor(value: T, next: N<T> | null = null, prev: N<T> | null = null) {this.value = value;this.next = next;this.prev = prev;}
}class LinkedList<T> implements List<T> {private head: N<T> | null = null;private tail: N<T> | null = null;public size = 0;add(element: T): void {const newNode = new N(element, null, this.tail);if (this.tail) {this.tail.next = newNode;} else {this.head = newNode;}this.tail = newNode;this.size++;}get(index: number): T | undefined {if (index < 0 || index >= this.size) {return undefined;}let current = this.head;for (let i = 0; i < index; i++) {current = current!.next;}return current?.value;}remove(element: T): boolean {let current = this.head;while (current) {if (current.value === element) {if (current.prev) {current.prev.next = current.next;} else {this.head = current.next;}if (current.next) {current.next.prev = current.prev;} else {this.tail = current.prev;}this.size--;return true;}current = current.next;}return false;}
}// 使用示例
const linkedList = new LinkedList<number>();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
console.log(linkedList.get(1)); // 输出: 2
console.log(linkedList.size); // 输出: 3
linkedList.remove(2);
console.log(linkedList.get(1)); // 输出: 3

3 )说明

  • 首先,我们定义了一个 List 接口,它规定了链表需要实现的基本方法:

    • 添加元素(add)
    • 获取指定位置的元素(get)
    • 获取链表大小(size)
    • 以及删除元素(remove)
    • 这个接口为后续的链表实现提供了统一的规范
  • 在 LinkedList 的实现中,节点被定义为一个名为 N 的内部类

    • 每个节点包含三个属性:value 用于存储数据,next 指向下一个节点,prev 指向前一个节点
    • 这样的结构使得链表能够双向遍历,从而更容易实现某些操作,如删除节点
  • LinkedList 类实现了 List 接口,并包含了维护链表状态的重要属性

    • head 指向链表的第一个节点,tail 指向链表的最后一个节点,size 记录链表的大小
  • 添加元素:add 方法在链表尾部添加一个新节点

    • 首先,创建一个新的节点,并设置其 next 为 null,prev 为当前的尾节点
    • 然后,更新尾节点为新节点,并如果原链表为空(即 head 和 tail 都为 null)
    • 则将 head 也指向新节点, 最后,链表的大小加一
  • 获取元素:get 方法通过遍历链表找到指定位置的元素

    • 它首先检查索引是否合法,然后从 head 开始遍历,直到找到对应位置的节点或遍历完整个链表
    • 这个过程的时间复杂度是 O(n),其中 n 是链表的大小
  • 删除元素:remove 方法遍历链表,查找并删除指定的元素

    • 当找到匹配的节点时,它更新相邻节点的指针以跳过该节点
    • 并调整 head 或 tail 如果被删除的是头节点或尾节点。最后,链表的大小减一
  • 总结

    • 双向链表 LinkedList 的实现简单而高效,通过双向指针实现了灵活的节点操作
    • 它的主要优势在于插入和删除节点时的性能,尤其是当需要在特定位置进行这些操作时
    • 然而,链表在随机访问元素方面的性能不如数组,因为需要从链表头部开始遍历以找到指定位置的元素
    • 在实际应用中,链表通常用于需要频繁插入和删除元素的场景,如实现缓存、LRU(最近最少使用)算法等
    • 而数组则更适用于需要频繁访问元素的场景,如搜索、排序等
    • 因此,在选择使用链表还是数组时,需要根据具体的应用场景和需求进行权衡

相关文章:

Typescript高级: 对泛型和多态的应用, 实现Java中的ArrayList和LinkedList

ArrayList 1 ) 概述 在Java中&#xff0c;ArrayList是一个非常常用且强大的数据结构&#xff0c;它提供了动态数组的功能能够方便地添加、删除和访问元素。在TypeScript中&#xff0c;虽然并没有内置的ArrayList类型但我们可以通过类与接口来模拟实现ArrayList的功能 2 &…...

正则表达式常用特殊字符(元字符)说明

正则表达式中包含多种特殊字符&#xff08;也称作元字符&#xff09;&#xff0c;它们具有特定的含义&#xff0c;用于构建复杂的匹配模式。以下是一些常用的特殊字符序列及其含义&#xff1a; \d - 匹配任何数字&#xff0c;等同于 [0-9]。\D - 匹配任何非数字字符&#xff0…...

使用hdc TCP模式无线方式连接OpenHarmony设备

本文将介绍如何使用hdc工具 tcp模式以无线的方式连接OpenHarmony设备。 1. usb连接方式切换为tcp模式。 将usb线将OpenHarmony设备和电脑端连接&#xff0c;并且将两个连接至同一个局域网。 # 执行 tmode port port-number&#xff0c;port-number设置为端口号。 hdc tmode …...

杂记-记一次前端打包问题解决过程

背景 若干年没更新发布的前端项目&#xff0c;突然来了个小需求&#xff0c;需求完成耗时5min&#xff0c;打包问题解决2小时 问题 error commander12.0.0: The engine “node” is incompatible with this module. Expected version “>18”. Got “10.22.1” 这个错误…...

维修ABB示教器主板DSQC679 3HAC 033624-001 /R机器人液晶显示屏深圳捷达工控维修

ABB 机器人示教器是工业环境中用于对机器人系统进行编程和控制的重要工具。这些手持设备允许操作员与机器人交互、输入命令并教它们特定的动作和任务。 每个 ABB 机器人示教器均专为用户友好型操作而设计&#xff0c;具有直观的界面和易于使用的人体工学设计。有多种型号可供选…...

原子学习笔记3——点亮 LED

一、应用层操控设备的两种方式 应用层如何操控底层硬件&#xff0c;同样也是通过文件 I/O 的方式来实现&#xff0c;设备文件便是各种硬件设备向应用层提供的一个接口&#xff0c;应用层通过对设备文件的 I/O 操作来操控硬件设备&#xff0c;譬如 LCD 显示屏、串口、按键、摄像…...

齐护K210系列教程(十八)_识别条码

识别条码 联系我们 将识别到的条形码内容打印输出并显示 测试条形码可以到如下网站得到&#xff1a;http://www.jsons.cn/barcode/ 4&#xff0c;课程资源 课程程序下载&#xff1a;【18条形码】 联系我们 扫码 或者点这里加群了解更多&#xff01; Created by qdprobot...

K折交叉验证

训练数据稀缺&#xff0c;无法构成验证集。 所以我们将训练数据分为k个子集。 执行k次模型训练和验证。每次在k-1个子集上进行训练&#xff0c; 并在剩余的一个子集&#xff08;该轮没有训练的子集&#xff09;上进行验证。 最后&#xff0c;这k次实验结果取平均来估计训练和验…...

Docker 的 Ubuntu 操作系统镜像

Debian 和 Ubuntu 都是目前较为流行的 Debian 系列 的服务器操作系统&#xff0c;十分适合研发场景。 Debian 和 Ubuntu 属于同一系列的发行版。Debian 是由 Ian Murdock 在 1993 年创建的最初的发行版。Ubuntu 是 Mark Shuttleworth 在 2004 年基于 Debian 创建的发行版。 Li…...

【Python】Python中的logging模块介绍和示例

Python中的logging模块是一个强大的内置模块&#xff0c;用于记录和跟踪应用程序的运行过程。它提供了灵活的日志记录功能&#xff0c;可以将日志消息输出到多个目标&#xff08;如控制台、文件、远程服务器等&#xff09;&#xff0c;并支持不同的日志级别。以下是logging模块…...

PXIe规格i3/i5/i7单板计算机控制器

是专为PXIe混合测试系统设计的主控制器&#xff0c;3U 12HP PXIe规格。该产品采用Intel Core™i3/i5/i7 第四代高性能处理器&#xff0c;内存可支持高达16G DDR3L。该系统PXI Express的link配置为通用的4Port 4lane的模式&#xff0c;数据吞吐量高达8GB/S。 CX786x提供丰富灵活…...

弱网对抗的策略有哪些?

在弱网环境下&#xff0c;数据传输可能会面临丢包、延迟、抖动等问题&#xff0c;因此采取合适的弱网对抗策略对于确保数据传输的稳定性和可靠性至关重要。以下是一些常见的弱网对抗策略&#xff1a; 数据压缩&#xff1a;使用压缩算法如Gzip、Brotli等对数据进行压缩&#xf…...

如何通过OMS加快大表迁移至OceanBase

OMS&#xff0c;是OceanBase官方推出的数据迁移工具&#xff0c;能够满足众多数据迁移场景的需求&#xff0c;现已成为众多用户进行数据迁移同步的重要工具。OMS不仅支持多种数据源&#xff0c;还具备全量迁移、增量同步、数据校验等功能&#xff0c;并能够对分表进行聚合操作&…...

讨论:WGS84与CGCS2000的坐标系怎么互转

前言&#xff1a; 今天我们要讨论一个问题&#xff1a;WGS84与CGCS2000的坐标系怎么互转&#xff1f; 对于有一定基础的朋友应该知道&#xff0c;WGS84和CGCS2000属于不同的椭球&#xff0c;如果进行严密的数学转换&#xff0c;是需要建立参数模型之后&#xff0c;再进行转换&…...

SpringCloud面试题

SpringCloud常见组件有哪些 注册中心组件&#xff1a;Eureka、Nacos 负载均衡组件&#xff1a;Ribbon 远程调用组件&#xff1a;OpenFeign 网关组件&#xff1a;Zuul、Gateway 服务保护组件&#xff1a;Hystrix、Sentinel 服务配置管理组件&#xff1a;SpringCloudConfig、Nac…...

深入了解Java Stream中的Collectors.partitioningBy()

在Java编程中&#xff0c;Stream API是一种强大的工具&#xff0c;它提供了处理集合数据的便捷方式。而Stream API中的Collectors.partitioningBy()方法则是其中一个十分有用的函数&#xff0c;它允许我们根据指定的条件将元素分成两个组。在本文中&#xff0c;我们将深入探讨这…...

下拉多选【bootstrap-multiselect】

1、引入资源 <link rel="stylesheet" href="${components}/bootstrap/css/bootstrap-multiselect.css"> <script src="${components}/bootstrap/js/bootstrap-multiselect.js"></script> 2、初始化 $("#topic-select&qu…...

建筑(八大员)报考条件

建筑八大员报考时间2024 建筑八大员每年考两次,上半年的考试时间一般在5-6月份,下半年的考试时间一般在10月左右。报名在考前2个月进行&#xff0c;2024年的考试时间和次数可能因省份而异&#xff0c;以住建厅通知为准。建筑八大员报考条件2024 1、年龄在18周岁以上(含18周…...

_remote.repositories作用

问题描述 明明我本地有某个依赖但是却还是报错&#xff0c;原因就是存在_remote.repositories且你的远程仓库中找不到该依赖&#xff0c;可能发生在你修改了远程仓库或镜像时。 例子 本地有这个依赖&#xff0c;但是报错。 解决 删除_remote.repositories文件&#xff0…...

2.3 Spark运行架构与原理

Spark运行架构由SparkContext、Cluster Manager和Worker构成。在集群模式下&#xff0c;Driver进程初始化SparkContext并向Cluster Manager申请资源&#xff0c;后者根据算法在Worker节点上启动Executor。Executor负责任务执行&#xff0c;反馈状态给Cluster Manager。任务由Ta…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…...