数据结构——用链表实现Map

news2024/11/15 22:48:58

目录

一、映射(Map)

二、代码实现

1.建立接口

2.方法实现

(1)映射的建立

键(key)和值(val)的建立

重写toString方法

(2)构造方法

(3)判断是否为空

(4)添加元素

(5)修改元素

(6)打印映射

(7)判断元素是否存在

(8)获取元素个数

(9)获取元素

(10)删除元素

3.方法调用

 三、对应题目


一、映射(Map)

映射(Maps)用于存储键值对,常见的实现有 HashMap 和 TreeMap。

在Java方法中可以直接调用

Map<String, Integer> hashMap = new HashMap<>();
Map<String, Integer> treeMap = new TreeMap<>();

HashMap:

  • 特点: 基于哈希表实现的键值对存储结构。
  • 优点: 高效的查找、插入和删除操作。
  • 缺点: 无序,不保证顺序。

TreeMap:

  • 特点: 基于红黑树实现的有序键值对存储结构。
  • 优点: 有序,支持按照键的顺序遍历。
  • 缺点: 插入和删除相对较慢。

映射是存储数据对(key,value)的数据结构

根据键(key),寻找值(value)

二、代码实现

1.建立接口

package com.algo.lesson.lesson05.map;

public interface SelfMap<K,V> {
    //判断集合是否为空
    boolean isEmpty();
    //获取集合中元素的个数
    int getSize();
    //判断key是否存在
    boolean containsKey(K key);
    //根据key获取值
    V fetValueByKey(K key);
    //向集合中添加元素
    void put(K key,V val);
    //删除集合中的元素(根据key删除)
    boolean removeByKey(K key);
    //修改key修改值
    void set(K key ,V val);
    //打印map集合中的所有元素【key:val】
    void show();
}

2.方法实现

(1)映射的建立

键(key)和值(val)的建立
K key;
        V val;
        Node next;

        public Node(K key, V val) {
            this.key = key;
            this.val = val;
            this.next = null;
        }

        public Node(K key, V val, Node next) {
            this(key, val);
            this.next = next;
        }

 private Node<K, V> head;
    private int size;
重写toString方法

打印的时候,为了能方便我们观察,我们可以重写toString方法,按照我们希望的格式去输出

@Override
        public String toString() {
            return "[" + this.key + ":" + this.val + "]";
        }
    }

(2)构造方法

public LinkedData() {
        Node<K, V> dummyHead = new Node(null, null);
        this.head = dummyHead;
        this.size = 0;
    }

(3)判断是否为空

public boolean isEmpty() {
        return this.size == 0;
    }

(4)添加元素

头部添加

public void addHead(K key, V val) {
        add(0, key, val);
    }

    public void add(int index, K key, V val) {
        if (index < 0 || index > this.size) {
            throw new IllegalArgumentException("index is invalid.");
        }
        Node<K, V> node = new Node(key, val);
        Node<K, V> pre = this.head;
        for (int i = 1; i <= index; i++) {
            pre = pre.next;
        }
        node.next = pre.next;
        pre.next = node;
        this.size++;
    }

(5)修改元素

传入键和值,返回boolean类型判断是否修改成功

public boolean set(K key,V val){
        Node<K, V> curNode = this.head.next;
        while (curNode != null) {
            if (curNode.key.equals(key)) {
                curNode.val=val;
                return true;
            }
            curNode = curNode.next;
        }
        return false;
    }

(6)打印映射

@Override
    public String toString() {
        Node<K, V> curNode = this.head.next;
        StringBuilder sb = new StringBuilder();
        while (curNode != null) {
            sb.append(curNode + "-->");
            curNode = curNode.next;
        }
        sb.append("null");
        return sb.toString();
    }

(7)判断元素是否存在

 public boolean contain(K key) {
        Node<K, V> curNode = this.head.next;
        while (curNode != null) {
            if (curNode.key.equals(key)) {
                return true;
            }
            curNode = curNode.next;
        }
        return false;
    }

(8)获取元素个数

public int getSize() {
        return this.size;
    }

(9)获取元素

根据键(key)获取值(val)

 public V get(K key) {
        Node<K, V> curNode = this.head.next;
        while (curNode != null) {
            if (curNode.key.equals(key)) {
                return curNode.val;
            }
            curNode = curNode.next;
        }
        return null;
    }

(10)删除元素

返回boolean值,判断是否删除成功

public boolean remove(K key) {
        Node<K, V> pre = this.head;
        while (pre.next != null) {
            Node<K, V> delNode = pre.next;
            if (delNode.key.equals(key)) {
                pre.next = pre.next.next;
                delNode.next = null;
                this.size--;
                return true;
            }
            pre = pre.next;
        }
        return false;
    }

3.方法调用

        继承SelfMap的接口,将其中的方法全部重写,然后进行调用,调取自己已经写好的代码,以此来实现Map

package com.algo.lesson.lesson05.map;

public class LinkedMap<K, V> implements SelfMap<K, V> {

    private LinkedData<K, V> data;

    public LinkedMap(){
        this.data=new LinkedData<>();
    }

    @Override
    public boolean isEmpty() {
        return this.data.isEmpty();
    }

    @Override
    public int getSize() {
        return this.data.getSize();
    }

    @Override
    public boolean containsKey(K key) {
        return this.data.contain(key);
    }

    @Override
    public V fetValueByKey(K key) {
        return this.data.get(key);
    }

    @Override
    public void put(K key, V val) {
        this.data.addHead(key,val);
    }

    @Override
    public boolean removeByKey(K key) {
        return this.data.remove(key);
    }

    @Override
    public void set(K key, V val) {
        boolean ret= this.data.set(key,val);
        System.out.println(ret?"successful":"failed");
    }

    @Override
    public void show() {
        System.out.println(this.data);
    }
}

 三、对应题目

350. 两个数组的交集 II力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目利用映射(哈希表)来解决,感兴趣可以去LeetCode上尝试一下

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        if(nums1.length>nums2.length){
            return intersect(nums2,nums1);
        }
        Map<Integer,Integer>map=new HashMap<Integer,Integer>();
        for(int num:nums1){
            int count=map.getOrDefault(num,0)+1;
            map.put(num,count);
        }
        int[]intersection=new int[nums1.length];
        int index=0;
        for(int num:nums2){
            int count=map.getOrDefault(num,0);
            if(count>0){
                intersection[index++]=num;
                count--;
                if(count>0){
                    map.put(num,count);
                }else{
                    map.remove(num);
                }
            }
        }
        return Arrays.copyOfRange(intersection,0,index);
    }
}

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

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

相关文章

详解Mockito

详解Mockito 1. Mockito简介 在我们的编程世界中&#xff0c;测试是一个非常重要的环节&#xff0c;它能帮助我们确保代码的质量和稳定性。而在众多的测试方法中&#xff0c;Mock测试是一种非常有效的手段。 1.1 什么是 Mock 测试 Mock测试&#xff0c;顾名思义&#xff0c;…

夹耳式骨传导耳机怎么戴?有什么注意事项吗

骨传导耳机是靠震动我们的颅骨来播放声音的耳机&#xff0c;它的厉害之处在于不用塞进耳朵里&#xff0c;所以不会让耳朵感到堵塞。这意味着在运动、听歌、打电话等各种活动的时候&#xff0c;它们可以提供一个非常特别的体验。而骨传导耳机里有一种类别叫做夹耳式骨传导耳机&a…

2024初学编曲免费软件FL Studio21.2.2

FL Studio在业内也被称作“水果”软件&#xff0c;这是一款功能强大、简单易上手的专业编曲软件。软件中的音效插件库拥有超过25种音效插件&#xff0c;能够帮助激发我们的创作灵感。而FL Studio中文还推出了训练营课程&#xff0c;初学者可以在训练营中进行编曲知识的学习&…

Java多线程--线程的生命周期

文章目录 一、JDK1.5之前&#xff1a;5种状态五种状态1、新建2、就绪3、运行4、阻塞5、死亡 二、JDK1.5及之后&#xff1a;六种状态 Java语言使用 Thread类及其子类的对象来表示 线程&#xff0c;在它的一个完整的生命周期中通常要经历如下一些状态。 一、JDK1.5之前&#xf…

【Java面试】Mysql

目录 sql的执行顺序索引的优点和缺点怎么避免索引失效(也属于sql优化的一种)一条sql查询非常慢&#xff0c;我们怎么去排查和优化&#xff1f;存储引擎 MylSAM和InnoDB、Memory的区别事务的四大特性(ACID)脏读、不可重复读、幻读事务的隔离级别&#xff1f;怎么优化数据库SQL优…

Java中SimpleDateFormat时YYYY与yyyy以及HH和hh的区别注意踩坑

场景 Java开发手册中为什么要求SimpleDateFormat时用y表示年&#xff0c;而不能用Y&#xff1a; Java开发手册中为什么要求SimpleDateFormat时用y表示年&#xff0c;而不能用Y_simpledateformat 怎么确定y就是年-CSDN博客 在使用SimpleDateFormat在获取当前日期时因使用了YY…

【DDD】学习笔记-软件开发团队的沟通与协作

领域驱动设计的核心是“领域”&#xff0c;因此要运用领域驱动设计&#xff0c;从一开始就要让团队走到正确的点儿上。当我们组建好了团队之后&#xff0c;应该从哪里开始&#xff1f;不是 UI 原型设计、不是架构设计、也不是设计数据库&#xff0c;这些事情虽然重要但却非最高…

STM32F1之RTC实时时钟(Unix时间戳)

目录 1. Unix时间戳 2. UTC/GMT 3. 时间戳转换 3.1 time_t 3.2 struct tm 3.3 char * 3.4 时间戳的使用 实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器&#xff0c;在相应软件配置下&#xff0c;可提供时钟日历的功能。修改计数器的值可以重新设置…

leetcode hot100 组合总和Ⅲ

本题中&#xff0c;要求我们求在1-9范围内&#xff0c;满足k个数的和为n的组合&#xff08;组合是无序的&#xff0c;并且题目中要求不可以重复&#xff09;。 这种组合问题依旧需要用回溯算法来解决。因为我们没办法控制产生k层for循环。回溯算法的过程是构建树结构&#xff…

巴厘行记(二)——乌布之夜

欢迎览阅《巴厘行记》系列文章 巴厘行记巴厘行记&#xff08;一&#xff09;——海神庙 巴厘行记&#xff08;二&#xff09;——乌布之夜 巴厘行记&#xff08;三&#xff09;——Auntie和Mudi 巴厘行记&#xff08;四&#xff09;——乌布漫游 巴厘行记&#xff08;五&a…

【学网攻】 第(10)节 -- 路由器单臂路由配置

系列文章目录 目录 系列文章目录 文章目录 前言 一、单臂路由是什么&#xff1f; 二、实验 1.引入 实验拓扑图 PC配置 Sw配置 Router配置 实验验证 总结 文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交…

Qt使用中文字符串乱码的问题

文章目录 vs编译器下第一种解决方式第二种解决方式 Qt编译器下 我们在使用qt的时候有时候会遇到打印中文字符串的时候出现中文乱码的问题&#xff0c;主要是由于Qt的QString字符串存储的方式是使用utf-8的编码方式&#xff0c;如果我们本地的文件是使用GBK方式的编码再使用中文…

Spring: alibaba代码规范校验工具checkstyle

文章目录 一、idea配置checkstyle插件二、激活CheckStyle三、配置自动格式化功能四、使用代码格式化 一、idea配置checkstyle插件 下载 Intellij IDEA Checkstyle 插件&#xff1a;File -> setting -> plugin通过关键字CheckStyle-IDEA搜索并安装。 安裝完成后重启idea…

wsl下安装ros2问题: Unable to locate package ros-humble-desktop 解决方案

❗ 问题 在wsl&#xff08;Ubuntu 22.04版本&#xff09;下安装ros的过程中&#xff0c;在执行命令 $ sudo apt install ros-humble-desktop一直弹出报错&#xff1a;Unable to locate package ros-humble-desktop 前面设置编码和添加源的过程中一直没有出现其他问题&#…

使用Docker部署MySQL并结合内网穿透实现远程访问本地数据库

文章目录 前言1 .安装Docker2. 使用Docker拉取MySQL镜像3. 创建并启动MySQL容器4. 本地连接测试4.1 安装MySQL图形化界面工具4.2 使用MySQL Workbench连接测试 5. 公网远程访问本地MySQL5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 前言 本文主…

【第五天】蓝桥杯备战

1、金币 https://www.lanqiao.cn/problems/357/learning/ 解法&#xff1a;暴力 import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scan new Scanner(System.in);//在此输入…

Oracle分栏(非分页)查询

不知道Oracle怎么进行数据分栏(分栏: 因数据列过长, 部分数据作为新列显示). 在这里先记录一下粗浅的查询方法. 数据源例子: select 日用百货 as cat, 手电筒 as name, 20 as amount, 2024-01-27 as dt from dualunion allselect 餐饮美食 as cat, 鸡公煲 as name, 15.9 as amo…

79 C++对象模型探索。数据语义学 - 进程内存空间布局分析

不同的数据在内存中会有不同的保存时机&#xff0c;和保存位置&#xff0c;这一节就分析这个。 当运行一个可执行文件时候&#xff0c;操作系统就会把这个可执行文件加载到内存&#xff1b;此时进程有一个虚拟的地址空间&#xff08;内存空间&#xff09;&#xff0c;如下图&a…

什么是SQL,什么是MYSQL?MYSQL的架构以及SQL执行语句的过程是什么?有哪些数据库的类型?一篇文章带你弄懂!

文章目录 前言一、为什么需要数据库二、数据库的相关概念1.什么是结构化查询语言 (SQL)2.什么是数据库管理系统 (DBMS)3.什么是 MySQL 数据库 三、数据库分类1.关系型数据库&#xff08;SQL&#xff09;2.非关系型数据库&#xff08;NoSQL&#xff09; 四、MYSQL架构1.各组件功…

奇怪问题说 - 测试篇

文章目录 1.什么是软件测试2.软件测试和开发的区别3.软件测试的发展&#xff1a;4.软件测试岗位5.软件测试在不同类型公司的定位6.一个优秀的软件测试人员具备的素质6.1综合能力6.2掌握自动化测试技术6.3优秀的测试用例设计能力6.4探索性思维6.5有责任感和一定的压力 7.软件测试…