鸿蒙系统开发【网络管理】

news2024/11/24 20:09:29

网络管理

介绍

此Demo展示如何查询网络详情、域名解析、网络状态监听等功能。

效果预览:

1

使用说明:

1.启动应用,在点击检查网络网络详情网络连接信息后,展示对应的信息;

2.在域名解析的模块下,输入对应的域名后,点击域名解析,展示解析的域名ip地址;

3.在网络监听模块下,开启网络监听后,展示当前监听的网络信息;关闭网络监听后,停止监听网络信息。

具体实现

使用@ohos.net.connection(网络连接管理)接口实现网络的详情、域名解析、网络监听等功能。代码:Index.ets

/*
 *
 *  * Copyright (c) 2023 Huawei Device Co., Ltd.
 *  * Licensed under the Apache License, Version 2.0 (the 'License');
 *  * you may not use this file except in compliance with the License.
 *  * You may obtain a copy of the License at
 *  *
 *  *     http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  * Unless required by applicable law or agreed to in writing, software
 *  * distributed under the License is distributed on an 'AS IS' BASIS,
 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  * See the License for the specific language governing permissions and
 *  * limitations under the License.
 *
 */

import { connection } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { CommonConstant as Const } from '../common/Constant';
import { promptAction } from '@kit.ArkUI';
import { Logger } from '../utils/Logger';

@Entry
@Component
struct Index {
  @State networkId: string = Const.NETWORK_ID;
  @State netMessage: string = Const.INIT_NET_MESSAGE;
  @State connectionMessage: string = Const.INIT_CONNECTION_MESSAGE;
  @State netStateMessage: string = '';
  @State hostName: string = '';
  @State ip: string = '';
  private controller: TabsController = new TabsController();
  private netHandle: connection.NetHandle | null = null;
  private netCon: connection.NetConnection | null = null;
  scroller: Scroller = new Scroller();

  aboutToDisappear(): void {
    this.unUseNetworkRegister;
  }

  build() {
    Column() {
      Text($r('app.string.network_title'))
        .fontSize($r('app.float.title_font_size'))
        .fontWeight(FontWeight.Bold)
        .textAlign(TextAlign.Start)
        .margin({ left: Const.WebConstant_TEN_PERCENT })
        .width(Const.WebConstant_FULL_WIDTH)

      Tabs({ controller: this.controller }) {
        TabContent() {
          Column() {
            Scroll() {
              Column() {
                Row() {
                  Column() {
                    Text($r('app.string.check_network'))
                      .fontSize($r('app.float.font_size'))
                      .padding({ top: $r('app.float.md_padding_margin'), left: $r('app.float.md_padding_margin') })
                      .fontWeight(FontWeight.Bold)
                      .align(Alignment.Start)
                      .width(Const.WebConstant_FULL_WIDTH)
                    Text(this.networkId)
                      .fontSize($r('app.float.font_size'))
                      .padding($r('app.float.md_padding_margin'))
                      .align(Alignment.Start)
                      .opacity($r('app.float.opacity'))
                      .width(Const.WebConstant_FULL_WIDTH)
                  }
                  .width(Const.WebConstant_SEVENTY_PERCENT)

                  Column() {
                    Button($r('app.string.check'))
                      .fontSize($r('app.float.sm_font_size'))
                      .height(Const.WebConstant_BUTTON_HEIGHT)
                      .margin({ top: $r('app.float.md_padding_margin') })
                      .width(Const.WebConstant_BUTTON_SMALL_WIDTH)
                      .buttonStyle(ButtonStyleMode.NORMAL)
                      .onClick(() => {
                        this.isNetworkAccess();
                      })
                  }
                  .align(Alignment.TopStart)
                  .height(Const.WebConstant_FULL_HEIGHT)
                  .width(Const.WebConstant_THIRTY_PERCENT)
                }
                .borderRadius($r('app.float.md_border_radius'))
                .margin({ left: $r('app.float.md_padding_margin'), right: $r('app.float.md_padding_margin') })
                .width(Const.WebConstant_NINETY_PERCENT)
                .height(Const.WebConstant_TWELVE_PERCENT)
                .backgroundColor($r('app.color.text_background'))

                Row() {
                  Column() {
                    Text($r('app.string.network_detail'))
                      .fontSize($r('app.float.font_size'))
                      .padding({ top: $r('app.float.md_padding_margin'), left: $r('app.float.md_padding_margin') })
                      .fontWeight(FontWeight.Bold)
                      .height(Const.WebConstant_FORTY_PERCENT)
                      .width(Const.WebConstant_FULL_WIDTH)
                    Text(this.netMessage)
                      .fontSize($r('app.float.font_size'))
                      .padding($r('app.float.md_padding_margin'))
                      .opacity($r('app.float.opacity'))
                      .height(Const.WebConstant_SIXTY_PERCENT)
                      .width(Const.WebConstant_FULL_WIDTH)
                  }
                  .width(Const.WebConstant_SEVENTY_PERCENT)
                  .align(Alignment.TopStart)

                  Column() {
                    Button($r('app.string.detail'))
                      .fontSize($r('app.float.sm_font_size'))
                      .height(Const.WebConstant_BUTTON_HEIGHT)
                      .margin({ top: $r('app.float.md_padding_margin') })
                      .width(Const.WebConstant_BUTTON_SMALL_WIDTH)
                      .buttonStyle(ButtonStyleMode.NORMAL)
                      .onClick(() => {
                        this.getNetworkMessage();
                      })
                  }
                  .align(Alignment.TopStart)
                  .height(Const.WebConstant_FULL_HEIGHT)
                  .width(Const.WebConstant_THIRTY_PERCENT)
                }
                .borderRadius($r('app.float.md_border_radius'))
                .margin($r('app.float.md_padding_margin'))
                .width(Const.WebConstant_NINETY_PERCENT)
                .height(Const.WebConstant_FIFTEEN_PERCENT)
                .backgroundColor($r('app.color.text_background'))

                Row() {
                  Column() {
                    Text($r('app.string.network_connection_detail'))
                      .fontSize($r('app.float.font_size'))
                      .padding($r('app.float.md_padding_margin'))
                      .fontWeight(FontWeight.Bold)
                      .width(Const.WebConstant_FULL_WIDTH)
                      .align(Alignment.Start)
                    Text(this.connectionMessage)
                      .fontSize($r('app.float.font_size'))
                      .opacity($r('app.float.opacity'))
                      .width(Const.WebConstant_NINETY_PERCENT)
                      .align(Alignment.Start)
                  }
                  .width(Const.WebConstant_SEVENTY_PERCENT)
                  .justifyContent(FlexAlign.Start)

                  Column() {
                    Button($r('app.string.detail'))
                      .fontSize($r('app.float.sm_font_size'))
                      .height(Const.WebConstant_BUTTON_HEIGHT)
                      .margin({ top: $r('app.float.md_padding_margin') })
                      .width(Const.WebConstant_BUTTON_SMALL_WIDTH)
                      .buttonStyle(ButtonStyleMode.NORMAL)
                      .onClick(() => {
                        this.getConnectionProperties();
                      })
                  }
                  .width(Const.WebConstant_THIRTY_PERCENT)
                }
                .alignItems(VerticalAlign.Top)
                .borderRadius($r('app.float.md_border_radius'))
                .margin({
                  left: $r('app.float.md_padding_margin'),
                  right: $r('app.float.md_padding_margin'),
                  bottom: $r('app.float.xl_padding_margin')
                })
                .width(Const.WebConstant_NINETY_PERCENT)
                .backgroundColor($r('app.color.text_background'))

              }
              .alignItems(HorizontalAlign.Start)
            }
          }
          .height(Const.WebConstant_FULL_HEIGHT)
          .alignItems(HorizontalAlign.Start)
        }.tabBar(Const.FIRST_TABS_BAR)

        TabContent() {
          Column() {
            Search({ placeholder: Const.SEARCH_PLACEHOLDER })
              .margin({ left: $r('app.float.md_padding_margin'), right: $r('app.float.md_padding_margin') })
              .width(Const.WebConstant_NINETY_PERCENT)
              .searchButton(Const.SEARCH_BUTTON)
              .onSubmit((value: string) => {
                this.hostName = value;
                this.parseHostName(this.hostName);
              })

            TextArea({ text: this.ip })
              .fontSize($r('app.float.lg_font_size'))
              .width(Const.WebConstant_NINETY_PERCENT)
              .height(Const.WebConstant_FIFTY_PERCENT)
              .margin({ top: $r('app.float.md_padding_margin') })
              .borderRadius($r('app.float.md_border_radius'))
              .focusOnTouch(false)
          }
          .height(Const.WebConstant_FULL_HEIGHT)
          .justifyContent(FlexAlign.Start)

        }.tabBar(Const.SECOND_TABS_BAR)

        TabContent() {
          Column() {
            Row() {
              Text(Const.MONITOR_TITLE)
                .fontSize($r('app.float.font_size'))
                .margin($r('app.float.md_padding_margin'))
                .fontWeight(FontWeight.Medium)
              Blank()
              Toggle({ type: ToggleType.Switch, isOn: false })
                .selectedColor(Color.Blue)
                .margin({ right: $r('app.float.md_padding_margin') })
                .width($r('app.float.area_width'))
                .height(Const.WebConstant_BUTTON_HEIGHT)
                .onChange((isOn) => {
                  if (isOn) {
                    this.useNetworkRegister();
                  } else {
                    this.unUseNetworkRegister();
                  }
                })
            }
            .height($r('app.float.button_height'))
            .borderRadius($r('app.float.md_border_radius'))
            .margin({ left: $r('app.float.md_padding_margin'), right: $r('app.float.md_padding_margin') })
            .width(Const.WebConstant_NINETY_PERCENT)
            .backgroundColor($r('app.color.text_background'))

            TextArea({ text: this.netStateMessage })
              .fontSize($r('app.float.font_size'))
              .width(Const.WebConstant_NINETY_PERCENT)
              .height(Const.WebConstant_FIVE_HUNDRED)
              .margin($r('app.float.md_padding_margin'))
              .borderRadius($r('app.float.md_border_radius'))
              .textAlign(TextAlign.Start)
              .focusOnTouch(false)

            Button($r('app.string.clear'))
              .fontSize($r('app.float.font_size'))
              .width(Const.WebConstant_NINETY_PERCENT)
              .height($r('app.float.area_height'))
              .margin({
              left: $r('app.float.md_padding_margin'),
              right: $r('app.float.md_padding_margin'),
              bottom: $r('app.float.xxl_padding_margin')
            })
              .onClick(() => {
                this.netStateMessage = '';
              })
            Blank()
          }
          .height(Const.WebConstant_FULL_HEIGHT)
          .justifyContent(FlexAlign.Start)

        }.tabBar(Const.THIRD_TABS_BAR_THREE)
      }
      .barWidth(Const.WebConstant_EIGHTY_PERCENT)
    }
    .width(Const.WebConstant_FULL_WIDTH)
  }

  isNetworkAccess() {
    connection.hasDefaultNet((error: BusinessError) => {
      if (error) {
        this.networkId = Const.NETWORK_ERROR;
        Logger.error('hasDefaultNet error:' + error.message);
        return;
      }
      this.netHandle = connection.getDefaultNetSync();
      this.networkId = Const.NETWORK_ID + JSON.stringify(this.netHandle);
    })
  }

  getNetworkMessage() {
    if (this.netHandle) {
      connection.getNetCapabilities(this.netHandle, (error, netCap) => {
        if (error) {
          this.netMessage = Const.NETWORK_TYPE_ERROR;
          Logger.error('getNetCapabilities error:' + error.message);
          return;
        }
        let netType = netCap.bearerTypes;
        for (let i = 0; i < netType.length; i++) {
          if (netType[i] === 0) {
            this.netMessage = Const.CELLULAR_NETWORK;
          } else if (netType[i] === 1) {
            this.netMessage = Const.WIFI_NETWORK;
          } else {
            this.netMessage = Const.OTHER_NETWORK;
          }
        }
        this.netMessage += 'networkCap:' + JSON.stringify(netCap.networkCap) + '\n';
      })
    }
  }

  getConnectionProperties() {
    connection.getDefaultNet().then((netHandle: connection.NetHandle) => {
      connection.getConnectionProperties(netHandle, (error: BusinessError, connectionProperties: connection.ConnectionProperties) => {
        if (error) {
          this.connectionMessage = Const.CONNECTION_PROPERTIES_ERROR;
          Logger.error('getConnectionProperties error:' + error.code + error.message);
          return;
        }
        this.connectionMessage = Const.CONNECTION_PROPERTIES_INTERFACE_NAME + connectionProperties.interfaceName
          + Const.CONNECTION_PROPERTIES_DOMAINS + connectionProperties.domains
          + Const.CONNECTION_PROPERTIES_LINK_ADDRESSES + JSON.stringify(connectionProperties.linkAddresses)
          + Const.CONNECTION_PROPERTIES_ROUTES + JSON.stringify(connectionProperties.routes)
          + Const.CONNECTION_PROPERTIES_LINK_ADDRESSES + JSON.stringify(connectionProperties.dnses)
          + Const.CONNECTION_PROPERTIES_MTU + connectionProperties.mtu + '\n';
      })
    });
  }

  parseHostName(hostName: string) {
    this.ip = '';
    connection.getAddressesByName(hostName).then((data) => {
      for (let i = 0; i < data.length; i++) {
        this.ip += data[i].address + '\n';
      }
    })
      .catch((error: BusinessError) => {
        this.ip = Const.GET_ADDRESSES_ERROR;
        Logger.error('getAddressesByName error:' + error.message);
      })
  }

  useNetworkRegister() {
    this.netCon = connection.createNetConnection();
    this.netStateMessage += Const.REGISTER_NETWORK_LISTENER;
    this.netCon.register((error) => {
      if (error) {
        Logger.error('register error:' + error.message);
        return;
      }
      promptAction.showToast({
        message: Const.REGISTER_NETWORK_LISTENER_MESSAGE,
        duration: 1000
      });
    })
    this.netCon.on('netAvailable', (netHandle) => {
      this.netStateMessage += Const.NET_AVAILABLE + netHandle.netId + '\n';
    })
    this.netCon.on('netBlockStatusChange', (data) => {
      this.netStateMessage += Const.NET_BLOCK_STATUS_CHANGE + data.netHandle.netId + '\n';
    })
    this.netCon.on('netCapabilitiesChange', (data) => {
      this.netStateMessage += Const.NET_CAPABILITIES_CHANGE_ID + data.netHandle.netId
        + Const.NET_CAPABILITIES_CHANGE_CAP + JSON.stringify(data.netCap) + '\n';
    })
    this.netCon.on('netConnectionPropertiesChange', (data) => {
      this.netStateMessage += Const.NET_CONNECTION_PROPERTIES_CHANGE_ID + data.netHandle.netId
        + Const.NET_CONNECTION_PROPERTIES_CHANGE_CONNECTION_PROPERTIES + JSON.stringify(data.connectionProperties) + '\n';
    })
  }

  unUseNetworkRegister() {
    if (this.netCon) {
      this.netCon.unregister((error: BusinessError) => {
        if (error) {
          Logger.error('unregister error:' + error.message);
          return;
        }
        promptAction.showToast({
          message: Const.UNREGISTER_NETWORK_LISTENER_MESSAGE,
          duration: 1000
        });
        this.netStateMessage += Const.UNREGISTER_NETWORK_LISTENER;
      })
    } else {
      this.netStateMessage += Const.UNREGISTER_NETWORK_LISTENER_FAIL;
    }
  }
}

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

在这里插入图片描述

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!

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

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

相关文章

一款功能强大的免费开源卸载工具

BCUninstaller&#xff0c;也称为Bulk Crap Uninstaller&#xff08;简称BCU&#xff09;&#xff0c;是一款免费且开源的Windows平台专用程序卸载工具。它的主要功能是帮助用户高效地批量卸载不需要的应用程序和组件&#xff0c;从而优化系统性能。 BCUninstaller功能特点 批…

8.1 tomcat+jdk

接着昨天的 npm run serve 构建项目 npm run build ls ls dist/ vim dist/index.html [rootweb eleme_web]# cd /usr/local/nginx/conf/ [rootweb conf]# ls 将静态的项目移动到nginx中 [rootweb nginx]# cd conf.d/ [rootweb conf.d]# ls qd.conf [rootweb conf.…

有关 AI 与产品经理的三个暴论

最近跟朋友聊 AI 聊得挺多。往往是不管做什么的&#xff0c;凡是跟互联网有联系的&#xff0c;都挺兴奋&#xff0c;都在讨论 AI。 聊着聊着&#xff0c;有三个暴论浮出水面&#xff0c;跟各位分享。暴论归暴论&#xff0c;道理还是在的。 1. AI 带来的新技术&#xff0c;会带…

2024年中国大模型能力评测:谁是AI领域的真王者?

2024年中国大模型能力评测深度解析 随着人工智能技术的飞速发展&#xff0c;中国的大模型正迎来前所未有的机遇与挑战。近期发布的《2024年中国大模型能力评测》报告&#xff0c;揭示了这一领域的最新趋势、发展瓶颈以及未来方向。本文将基于该报告&#xff0c;带您深入了解中国…

ssh免密认证配置

一.首先要做root用户在sshd服务中的允许 [root172 ~]# vim /etc/ssh/sshd_configPermitRootLogin yes 二.监控动作 watch -n 1 "tail -n 3 /etc/passwd /etc/group;ls -l /home" 三.用户建立时的命令 1.纯净的实验环境 [root172 ~]# rm -fr ~/.ssh/ 2.生成密钥…

【初阶数据结构篇】冒泡排序和快速排序(中篇)

文章目录 冒泡排序和快速排序前言代码位置冒泡排序快速排序递归法实现hoare版本挖坑法lomuto前后指针递归法复杂度分析 非递归法实现 冒泡排序和快速排序 前言 本篇以排升序为例 代码位置 gitee 冒泡排序 动图理解 作为第一个接触的排序算法&#xff0c;冒泡排序想必大…

Monaco 使用 SelectionRange

Monaco 中有个展开选择的功能&#xff0c;默认如果我们选择 function&#xff0c;扩展选择就会选择到行尾&#xff0c;再扩展就会选中整个函数&#xff0c;效果如下&#xff1a; Monaco 可以自定义选择范围&#xff0c;通过 registerSelectionRangeProvider 注册 selectionRang…

yarn运行失败

目录 1.项目初始化失败2.powershell管理身份运行3.正常4.项目启动5.接下来安装yarn过程 使用vuepress构建静态文档网站1.标题This is an H1This is an H2 this is H1this is H2this is H6 2.字体3.分割线4.引用引用接着 5.列表无序列表有序列表 6.表格7.代码 1.项目初始化失败 …

【通俗理解】主动推理模型——从感知到决策的智慧桥梁

【通俗理解】主动推理模型——从感知到决策的智慧桥梁 主动推理模型的类比 你可以把主动推理模型比作一个“智慧导航仪”&#xff0c;它能够帮助我们的大脑在感知世界、更新信念和做出决策的过程中找到最佳路径。 主动推理模型的核心作用 组件/步骤描述感知世界大脑通过感官接…

在vue3的开发环境中为什么使用vite而不是用webpack

1、vite在开发阶段没有打包过程&#xff0c;直接启动一个服务器 2、请求一个模块到开发服务器 3、开发服务器编译模块&#xff0c;根据页面用所需要的依赖去加载文件 4、加载完成后&#xff0c;开发服务器把编译的结果返回给页面 这使得提高了我们在开发阶段运行的效率 vite是…

【漏洞复现】搜狗输入法简单绕过Windows锁屏机制

免责申明 本公众号的技术文章仅供参考&#xff0c;此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息…

群晖NAS结合内网穿透工具实现远程连接内网SFTP服务传输文件

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

ABAP+json格式数据转换时参数为空没传值

CALL METHOD /UI2/CL_JSON>SERIALIZE 我们在ABAP传输json格式数据到外围系统时&#xff0c;会用到这个类方法 /UI2/CL_JSON>SERIALIZE CALL METHOD /UI2/CL_JSON>SERIALIZEEXPORTINGDATA LO_DATACOMPRESS XPRETTY_NAME /UI2/CL_JSON>PRETTY_M…

LiveBOS UploadFile.do 任意文件上传漏洞复现(XVE-2023-21708)

0x01 产品简介 LiveBOS(Live Business Object System)是顶点软件自主研发的以业务对象建模为核心的业务中间件及其集成开发工具,它通过业务模型建立直接完成软件开发的创新模式,支持各类基于WEB的专业应用软件与行业大型应用的开发。LiveBOS系统由三个相对独立的产品构成:…

DBA界中的ACE 是时候谢幕了

很多人把ACE当作神一样去膜拜! 还脑残地帮ACE去宣传,需要对ACE要有敬畏之心! ACE 全称是 America Certification Eloquent 首先由ORACLE公司 (美国公司) 在最近20年推出来的荣耀称号! 授予一些通过OCP,OCM认证的DBA在社区为其产品使用和推广做出贡献的荣耀称号 为什么我们…

实验21.实现 printf

已完成实验 已完成实验链接 简介 实验 21. 实现 printf 总结 简化系统调用和中断&#xff0c;用 eax 代表调用号参数&#xff0c;ebx,ecx,edx 来代表参数(syscall.c kernel.s) 添加 write 的系统调用接口(syscall.c, syscall-init.c, print.s) 注意&#xff1a;要更改 p…

Arbitrum Nitro交易速度压力测试实战:TPS性能评估全解析

Arbitrum Nitro 是一种基于以太坊的 Layer 2 扩展解决方案&#xff0c;旨在提高交易吞吐量并降低交易费用。为了全面评估其性能&#xff0c;我们需要进行了详细的压力测试。本文的目的是回顾一下我在实际测试过程中采用的方法&#xff0c;还有测试的思路。 我们的压力测试主要…

【Docker应用】快速搭建Plik服务结合内网穿透无公网IP远程访问传输文件

文章目录 前言1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 前言 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设…

页面路由怎么开发

首先删除它自带的页面 新建页面 Composition API 和 Options API 是 Vue.js 中两种不同的组件写法风格&#xff0c;它们用于定义 Vue 组件的结构和逻辑。我用的是Options API 配置路由 将它修改为需要的,按照上面的写法 如果component里面已经加了那么就不需要在上面加这是一种…

C++数据结构重要知识点(4)(map和set封装)

前面我们已经实现了红黑树&#xff0c;接下来我们需要将这个数据结构封装成map和set两个容器&#xff0c;其中很多地方的处理都有一定难度&#xff0c;下面会按照我的思路讲解map的改造 map成员变量如下&#xff0c;如果是第一次看到它&#xff0c;那么一定会很陌生&#xff0…