HarmonyOS实战开发-如何构建多种样式弹窗
介绍
本篇Codelab将介绍如何使用弹窗功能,实现四种类型弹窗。分别是:警告弹窗、自定义弹窗、日期滑动选择器弹窗、文本滑动选择器弹窗。需要完成以下功能:
- 点击左上角返回按钮展示警告弹窗。
- 点击出生日期展示日期滑动选择器弹窗。
- 点击性别展示文本滑动选择器弹窗。
- 点击兴趣爱好(多选)展示自定义弹窗。
相关概念
- 警告弹窗:显示警告弹窗组件,可设置文本内容与响应回调。
- 自定义弹窗: 通过CustomDialogController类显示自定义弹窗。
- 日期滑动选择器弹窗:根据指定范围的Date创建可以选择日期的滑动选择器,展示在弹窗上。
- 文本滑动选择器弹窗:根据指定的选择范围创建文本选择器,展示在弹窗上。
环境搭建
软件要求
- DevEco Studio版本:DevEco Studio 3.1 Release。
- OpenHarmony SDK版本:API version 9。
硬件要求
- 开发板类型:润和RK3568开发板。
- OpenHarmony系统:3.2 Release。
环境搭建
完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:
- 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:
2.搭建烧录环境。
- 完成DevEco Device Tool的安装
- 完成RK3568开发板的烧录
3.搭建开发环境。
- 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
- 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
- 工程创建完成后,选择使用真机进行调测。
代码结构解读
本篇Codelab只对核心代码进行讲解。
├──entry/src/main/ets // 代码区
│ ├──common
│ │ ├──constants
│ │ │ └──CommonConstants.ets // 常量类
│ │ └──utils
│ │ ├──CommonUtils.ets // 弹窗操作工具类
│ │ └──Logger.ets // 日志打印工具类
│ ├──entryability
│ │ └──EntryAbility.ets // 程序入口类
│ ├──pages
│ │ └──HomePage.ets // 主页面
│ ├──view
│ │ ├──CustomDialogWidget.ets // 自定义弹窗组件
│ │ ├──TextCommonWidget.ets // 自定义Text组件
│ │ └──TextInputWidget.ets // 自定义TextInput组件
│ └──viewmodel
│ └──HobbyModel.ets // 兴趣爱好model类
└──entry/src/main/resources // 资源文件目录
构建主页面
应用主页面采用Column容器嵌套自定义组件形式完成页面整体布局,效果如图所示:
从上面效果图可以看出,主界面由2个相同样式的文本输入框和3个相同样式的文本布局组成。我们可以将文本输入框抽取成TextInputWidget子组件。再将文本布局抽取成TextCommonWidget子组件。
- 在ets目录下,点击鼠标右键 > New > Directory,新建名为view的自定义子组件目录。然后在view目录下,点击鼠标右键 > New > ArkTS File,新建两个ArkTS文件,分别为TextInputWidget子组件、TextCommonWidget子组件。
- 文本输入框抽取成TextInputWidget子组件,效果如图所示:
// TextInputWidget.ets
@Component
export default struct TextInputWidget {// 文本框左侧图片private inputImage?: Resource; // 文本框提示private hintText?: Resource;build() {Row() {Image(this.inputImage)...TextInput({ placeholder: this.hintText })...}...}
}
3.文本布局抽取成TextCommonWidget子组件,效果如图所示:
// TextCommonWidget.ets
@Component
export default struct TextCommonWidget {// 显示内容@Link content: string;// 文字标题左侧图片private textImage?: Resource;// 文本标题private title?: Resource;// 点击事件回调onItemClick: () => void = () => {};build() {Row() {Image(this.textImage)...Text(this.title)...Text(this.content)...Image($r('app.media.ic_arrow'))....}.onClick(this.onItemClick)...}
}
4.在HomePage主界面引用TextInputWidget和TextCommonWidget子组件,然后初始化出生日期、性别、兴趣爱好默认数据。
// HomePage.ets
@Entry
@Component
struct HomePage {@State birthdate: string = '';@State sex: string = '';@State hobbies: string = '';build() {Column() {...TextInputWeight({inputImage: $r("app.media.ic_nickname"),hintText: $r("app.string.text_input_hint")})TextCommonWeight({textImage: $r("app.media.ic_birthdate"),title: $r("app.string.title_birthdate"),content: $birthdate,onItemClick: () => {CommonUtils.datePickerDialog((birthValue: string) => {this.birthdate = birthValue;});}}) TextCommonWeight({textImage: $r("app.media.ic_sex"),title: $r("app.string.title_sex"),content: $sex,onItemClick: () => {CommonUtils.textPickerDialog(this.sexArray, (sexValue: string) => {this.sex = sexValue;});}})TextInputWeight({inputImage: $r("app.media.ic_signature"),hintText: $r("app.string.text_input_signature")})TextCommonWeight({textImage: $r("app.media.ic_hobbies"),title: $r("app.string.title_hobbies"),content: $hobbies,onItemClick: () => {this.customDialogController.open();}})}...}
}
警告弹窗
点击主页面左上角返回按钮,通过CommonUtils.alertDialog方法弹出警告弹窗,提醒用户是否进行当前操作,效果如图所示:
// CommonUtils.ets
alertDialog(context: Context.UIAbilityContext) {AlertDialog.show({// 提示信息message: $r('app.string.alert_dialog_message'), // 弹窗显示位置alignment: DialogAlignment.Bottom,// 弹窗偏移位置offset: {dx: 0,dy: CommonConstants.DY_OFFSET},primaryButton: {...},secondaryButton: {// 退出应用context.terminateSelf();...}});
}
日期滑动选择器弹窗
点击出生日期选项,通过CommonUtils.datePickerDialog方法弹出日期选择器弹窗,根据需要选择相应时间,效果如图所示:
// CommonUtils.ets
datePickerDialog(dateCallback) {DatePickerDialog.show({// 开始时间start: new Date(CommonConstants.START_TIME),// 结束时间end: new Date(CommonConstants.END_TIME), // 当前选中时间selected: new Date(),// 是否显示农历lunar: false,onAccept: (value: DatePickerResult) => {let year = value.year as number;let month = value.month as number + CommonConstants.PLUS_ONE;let day = value.day as number;let birthdate: string = this.getBirthDateValue(year, month, day);dateCallback(birthdate);}});
}// 获取出生日期值
getBirthDateValue(year: number, month: number, day: number): string {let birthdate: string = `${year}${CommonConstants.DATE_YEAR}${month}` +`${CommonConstants.DATE_MONTH}${day}${CommonConstants.DATE_DAY}`;return birthdate;
} // HomePage.ets
build() {Column() {...TextCommonWeight({textImage: $r('app.media.ic_birthdate'),title: $r("app.string.title_birthdate"),content: $birthdate,onItemClick: () => {CommonUtils.datePickerDialog((birthValue: string) => {this.birthdate = birthValue;});}})...}...
}
文本滑动选择器弹窗
点击性别选项,通过CommonUtils.textPickerDialog方法弹出性别选择器弹窗,根据需要选择相应性别,效果如图所示:
// CommonUtils.ets
textPickerDialog(sexArray: Resource, sexCallback: (sexValue: string) => void) {TextPickerDialog.show({range: sexArray,selected: 0,onAccept: (result: TextPickerResult) => {sexCallback(result.value);},onCancel: () => {...}});
}// HomePage.ets
build() {Column() {...TextCommonWeight({textImage: $r('app.media.ic_sex'),title: $r("app.string.title_sex"),content: $sex,onItemClick: () => {CommonUtils.textPickerDialog(this.sexArray, (sexValue: string) => {this.sex= sexValue;});}})...}...
}
自定义弹窗
点击兴趣爱好选项,通过customDialogController.open方法弹出自定义弹窗,根据需要选择相应的兴趣爱好,效果如图所示:
自定义弹窗实现分为以下步骤:
- 在view目录下,点击鼠标右键 > New > ArkTS File,新建一个ArkTS文件,然后命名为CustomDialogWeight子组件。
- 在CustomDialogWeight的aboutToAppear方法,通过manager.getStringArrayValue方法获取本地资源数据进行初始化。
// CustomDialogWeight.ets
@State hobbyModels: HobbyModel[] = [];aboutToAppear() {let context: Context = getContext(this);if (CommonUtils.isEmpty(context) || CommonUtils.isEmpty(context.resourceManager)) {Logger.error(CommonConstants.TAG_CUSTOM, 'context or resourceManager is null');return;}let manager = context.resourceManager;manager.getStringArrayValue($r("app.strarray.hobbies_data").id, (error, hobbyArray) => {if (!CommonUtils.isEmpty(error)) {Logger.error(CommonConstants.TAG_CUSTOM, 'error = ' + JSON.stringify(error));} else {hobbyArray.forEach((hobbyItem: string) => {let hobbyModel = new HobbyModel();hobbyModel.label = hobbyItem;hobbyModel.isChecked = false;this.hobbyModels.push(hobbyModel);});}});
}
3.当用户点击确定按钮时,通过setHobbiesValue方法处理自定义弹窗选项结果。
// CustomDialogWeight.ets
@State hobbyModels: HobbyModel[] = [];
@Link hobbies: string;// 处理自定义弹窗选项结果
setHobbiesValue(hobbyModels: HobbyModel[]) {if (CommonUtils.isEmptyArr(hobbyModels)) {Logger.error(CommonConstants.TAG_CUSTOM, 'hobbyModels length is 0');return;}let hobbiesText: string = '';hobbiesText = hobbyModels.filter((isCheckItem: HobbyModel) => isCheckItem?.isChecked).map((checkedItem: HobbyModel) => {return checkedItem.label;}).join(CommonConstants.COMMA);if (hobbiesText.length > 0) {this.hobbies = hobbiesText;}
}build() {Column() {...Row() {Button($r('app.string.cancel_button')).dialogButtonStyle().onClick(() => {this.controller.close();})Blank()...Button($r('app.string.definite_button')).dialogButtonStyle().onClick(() => {this.setHobbiesValue(this.hobbyModels);this.controller.close();})}}...
}@Extend(Button) function dialogButtonStyle() {....
}
4.通过@Link修饰的hobbies把值赋给HomePage的hobbies,然后hobbies刷新显示内容。
// HomePage.ets
@State hobbies: string = '';
customDialogController: CustomDialogController = new CustomDialogController({builder: CustomDialogComponent({hobbies: $hobbies}),alignment: DialogAlignment.Bottom,customStyle: true,offset: {dx: 0,dy: CommonConstants.DY_OFFSET}
});build() {Column() {...TextCommonWeight({textImage: $r('app.media.ic_hobbies'),title: $r("app.string.title_hobbies"),content: $hobbies,onItemClick: () => {// 打开自定义弹窗this.customDialogController.open();}})}...
}
总结
您已经完成了本次Codelab的学习,并了解到以下知识点:
- 使用CustomDialogController实现自定义弹窗。
- 使用AlertDialog实现警告弹窗。
- 使用DatePickerDialog实现日期滑动选择弹窗。
- 使用TextPickerDialog实现文本滑动选择弹窗。
为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→《HarmonyOS教学视频》
HarmonyOS教学视频:语法ArkTS、TypeScript、ArkUI等.....视频教程
鸿蒙生态应用开发白皮书V2.0PDF:
获取完整版白皮书方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF》
鸿蒙 (Harmony OS)开发学习手册
一、入门必看
- 应用开发导读(ArkTS)
- ……
二、HarmonyOS 概念
- 系统定义
- 技术架构
- 技术特性
- 系统安全
- ........
三、如何快速入门?《做鸿蒙应用开发到底学习些啥?》
- 基本概念
- 构建第一个ArkTS应用
- ……
四、开发基础知识
- 应用基础知识
- 配置文件
- 应用数据管理
- 应用安全管理
- 应用隐私保护
- 三方应用调用管控机制
- 资源分类与访问
- 学习ArkTS语言
- ……
五、基于ArkTS 开发
- Ability开发
- UI开发
- 公共事件与通知
- 窗口管理
- 媒体
- 安全
- 网络与链接
- 电话服务
- 数据管理
- 后台任务(Background Task)管理
- 设备管理
- 设备使用信息统计
- DFX
- 国际化开发
- 折叠屏系列
- ……
更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册》
相关文章:
HarmonyOS实战开发-如何构建多种样式弹窗
介绍 本篇Codelab将介绍如何使用弹窗功能,实现四种类型弹窗。分别是:警告弹窗、自定义弹窗、日期滑动选择器弹窗、文本滑动选择器弹窗。需要完成以下功能: 点击左上角返回按钮展示警告弹窗。点击出生日期展示日期滑动选择器弹窗。点击性别展…...
《Effective C++》《构造/析构/赋值运算——7、为多态基类声明virtual析构函数》
文章目录 1、term7:Declare destructors virtual in polymorphic base classes2、总结3、相关面试题3.1 析构函数在什么情况下声明为虚函数 4、参考 1、term7:Declare destructors virtual in polymorphic base classes 带有多态性质的基类应该声明一个virtual析构函数&#x…...
Type-C一分二快充线智能分配方案
随着移动设备的普及和快充技术的迅猛发展,Type-C接口已成为众多手机、平板和笔记本电脑的标配。然而,在日常使用中,我们经常会遇到需要同时为多个设备充电的情况。这时,Type-C一分二快充线就显得尤为重要。为了更好地满足用户的充…...
利用python脚本,根据词条爬取百度图片(爬虫)
把广角,换成你的关键词就行 # -*- coding: utf-8 -*- """ Created on Wed Mar 29 10:17:50 2023 author: MatpyMaster """ import requests import os import redef get_images_from_baidu(keyword, page_num, save_dir):header {Us…...
java复原IP 地址(力扣Leetcode93)
复原IP 地址 力扣原题链接 问题描述 有效 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。 例如:“0.1.2.201” 和 “192.168.1.1” 是有效 IP 地址,…...
k8s的创建资源的流程图
背景 在k8s中创建资源需要经过几个流程的协作,包括认证模块,授权模块和资源管理模块的共同处理的结果 k8s的创建资源的流程图 第一步认证模块: k8s需要确保操作的客户端是合法的用户,并且不是仿冒的,也就是判断这个u…...
Android RecyclerView 滑动后选中的条目居中显示
话不多说先看效果: 实录效果视频如下 滚动居中 RecyclerView 在原有的RecyclerView 基础上操作,其他步骤不变,只是替换一下 manager 步骤 导入依赖 maven { url https://www.jitpack.io }//无限滚动implementation com.github.ZhaoChanghu:GalleryLayou…...
RPA-财务对账邮件应用自动化(客户对账机器人)
《财务对账邮件应用自动化》,将会使用邮箱的SMTP服务,小北把资源包绑定在这篇博客了 Uibot (RPA设计软件)———机器人的小项目友友们可以参考小北的课前材料五博客~ (本博客中会有部分课程ppt截屏,如有侵权请及请及时与小北我取得联系~) …...
Delphi模式编程
文章目录 Delphi模式编程涉及以下几个关键方面:**设计模式的应用****Delphi特性的利用****实际开发中的实践** Delphi模式编程的实例 Delphi模式编程是指在使用Delphi这一集成开发环境(IDE)和Object Pascal语言进行软件开发时,采用…...
flutter 自定义弹窗封装弹窗----在弹窗内实现部分窗体生命周期
小部件组件 可以在里面加装其他事件如HTTP接口访问 import package:flutter/material.dart;///执行弹窗动画封装 class ExecutionDialog extends StatefulWidget {// final String? title;// final String? message;// final Function? onExecute;//// const ExecutionDial…...
go语言 私用仓库包下载
设置私有仓库,这样访问的时候,url前缀就不加proxy和sumdb go env -w GOPRIVATE"code.xxx.cn" go env -w GONOPROXY"code.xxx.cn" go env -w GONOSUMDB"code.xxx.cn" 设置取消安全认证 go env -w GOINSECURE"code…...
Math类
java.lang.Math 提供了一系列静态方法用于科学计算,常用方法如下: abs 绝对值 acos,asin,atan,cos,sin,tan 三角函数 sqrt 平方根 pow(double a,double b) a的b次幂 max(double a,double b) 取大…...
Git 入门教程
Git 入门教程 一、Git 是什么? Git 是一个开源的分布式版本控制系统,用于追踪代码的改动。它可以帮助开发者协同工作,管理项目中的代码版本。 二、安装 Git 在开始使用 Git 之前,你需要在你的计算机上安装 Git。你可以从 Git …...
Linux网络配置(超详细)
Linux网络配置大全 Linux网络配置一.网络地址配置网络地址查看–ifconfig使用网络配置命令设置网络接口参数-ifconfig禁用(临时)或者重新激活网卡设置虚拟网络接口 修改网络配置文件网络接口配置文件 IP命令详解OPTIONS选项OBJECT对象 ip link 二、获取和修改主机名hostname查看…...
[自研开源] 数据集成之分批传输 v0.7
开源地址:gitee | github 详细介绍:MyData 基于 Web API 的数据集成平台 部署文档:用 Docker 部署 MyData 使用手册:MyData 使用手册 试用体验:https://demo.mydata.work 交流Q群:430089673 介绍 本篇基于…...
用 AI 编程-释放ChatGPT的力量
最近读了本书,是 Sean A Williams 写的,感觉上还是相当不错的。一本薄薄的英文书,还真是写的相当好。如果你想看,还找不到,可以考虑私信我吧。 ChatGPT for Coders Unlock the Power of AI with ChatGPT: A Comprehens…...
【快速解决】解决谷歌自动更新的问题,禁止谷歌自动更新,如何防止chrome自动升级 chrome浏览器禁止自动升级设置方法
目录 问题描述 解决方法 1、搜索栏搜索控制面板 2、搜索:服务 编辑 3、点击Windows工具 4、点击服务 5、禁止谷歌更新 问题描述 由于我现在需要装一个谷歌的驱动系统,但是目前的谷歌驱动系统的版本都太旧了,谷歌自身的版本又太新了…...
【Leetcode每日一题】模拟 - 替换所有的问号(难度⭐)(42)
1. 题目解析 题目链接:1576. 替换所有的问号 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 遍历字符串:从左到右逐个处理字符。 处理问号字符:对于每个问号字符,我们需…...
再见 mysql_upgrade
在数据库管理的世界里,随着技术的不断进步和业务的不断发展,数据库的版本升级成为了一个不可避免的过程。 MySQL 作为业界领先的开源关系型数据库管理系统,其版本迭代与功能优化同样不容忽视。 而在这个过程中,升级工具就显得尤为…...
.NET Core教程:入门与实践实例
.NET Core教程:入门与实践实例 在信息技术飞速发展的今天,掌握一门高效的编程技术成为了每个开发者不可或缺的技能。在众多编程框架中,.NET Core以其跨平台、高性能和易扩展的特性,受到了广大开发者的青睐。本文将通过实例&#…...
docker环境配置过程中的常见问题
1、pull镜像问题 docker pull jenkins/jenkins:lts Using default tag: latest Trying to pull repository docker.io/library/centos ... Get https://registry-1.docker.io/v2/library/centos/manifests/latest: Get https://auth.docker.io/token?scoperepository%3Alibr…...
精选2024年最佳项目管理系统!实用推荐与详细评测
随着企业规模的扩大,项目量也会呈几何倍的增长,项目管理系统就成了企业管理必不可少的一部分。2024年优秀的项目管理系统推荐。今年为大家带来Microsoft Project、Zoho Projects、Jira以及Wrike项目管理系统评测。 什么是项目管理系统? 项目…...
民航电子数据库:CAEMigrator迁移数据库时总是卡死
目录 一、场景二、异常情况三、排查四、应急方案 一、场景 1、对接民航电子数据库 2、将mysql数据库迁移到cae数据库 3、使用CAEMigrator迁移工具进行数据库迁移时,该工具会卡死(不清楚是否是部署cae服务的服务器资源导致) 二、异常情况 …...
数据结构 第6章 图(一轮习题总结)
数据结构 第6章 图 6.1 图的基本概念6.2 图的存储及基本操作6.3 图的遍历6.4 图的应用 6.1 图的基本概念(2 4 11) 6.2 图的存储及基本操作(1 12 13 15 16) 6.3 图的遍历(2 3 5 16) 6.4 图的应用 6.1 图的基…...
如何在智能交通系统中使用物联网技术提高道路安全和效率
在智能交通系统中,物联网(IoT)技术可以通过多种方式提高道路安全和效率。以下是利用物联网技术提高智能交通系统效能的具体方法: 1. 车与路、车与车通信(V2X):通过在道路上部署传感器和路侧单元…...
七大 QC 工具图的定义与示例(看这篇就够了)
前言 七大 QC 工具图是通过数值的方式进行数据分析的工具,分别是鱼骨图、直方图、柏拉图、散布图、管制图、检查图和层别图。其实,我们在日常生活与工作中经常看到它们,只是样子和名字对不上而已,今天写这篇文章就是为了帮助自己…...
【JavaScript算法】DOM树层级显示
题目描述: 上述表达式的输出结果为 [DIV] [P, SPAN, P, SPAN] [SPAN, SPAN]直接上代码 let tree document.querySelector(".a"); function traverseElRoot(elRoot) {const result [];function traverse(element, level) {if (!result[level]) {resul…...
MySql实战--全局锁和表锁 :给表加个字段怎么有这么多阻碍
今天我要跟你聊聊MySQL的锁。数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。而锁就是用来实现这些访问规则的重要数据结构。 根据加锁的范围,MySQL里面的锁大致可以分成…...
axios请求类型是文件流怎么显示报错信息
axios请求类型是文件流,但是报错信息的话没法显示,在request.js文件中更改一下request拦截器代码: service.interceptors.request.use(config > { ...... , error > { console.log(error, 报错报错) // 处理请求错误 if (error.respons…...
DataX 源码改造支持Mysql 8.X
文章目录 DataX 源码改造支持Mysql 8.X问题背景克隆源代码并修改重新打包生产环境发布DataX 源码改造支持Mysql 8.X 问题背景 今天在使用DataX同步数据的时候遇到一个问题,报错如下 错误信息为:java.sql.SQLException: No suitable driver found for ["jdbc:mysql://…...
如何做电子书网站/爱站小工具圣经
如果一个网站的页面有一个部位经常用到时,可以写一个单独的jsp页面 <jsp:include page"xx.jsp"/>这条代码,单独写个文件来联合起来,类似于一个通用的页面 例如网站顶部的登陆注册栏...
甘肃建设厅职称查询官方网站/东莞网站制作公司联系方式
1. 常用的几个函数 If(条件){语句 } else if (条件){语句 } else {语句 } swtich(条件){case 1:语句break;default :语句break; } for(条件){语句 } while(条件){语句 } do{语句 }while(条件); 注意,这里有个分号 a:语句 goto a; 不推荐使用,可以…...
苏州h5网站建设/软文案例500字
SpringBoot web开发 springboot使用: 1)创建SpringBoot应用,选择需要的模块 2)SpringBoot 已经默认将这些选中的场景配置好了(之前学的自动配置功能),只需要在配置文件中指定少量配置就可以运行起来 3&am…...
wordpress代码 lt/深圳网络营销推广培训
历史概况 1995年,Mat Nelson进入IBM,开始接触JAVA。 2000年,随着JAVA语言成熟, Mat Nelson这个狂热的玩家看到了创建这个“他一直想玩”的游戏的机会,着手开始创建Robocode。 2001年, IBM以 alpha…...
建设信用卡官方网站/培训心得体会800字
电大计算机科学与技术c语言各章练习题答案各章练习题答案第1章 C语言概述1.1 简答题1 答:C语言单词分为保留字、标识符、字面常量、运算符和分隔符5类。2 答:首字符必须是英文字母或下划线;其余位置上的字符必须是英文字母、十进制数字符号或…...
国外唯美flash个人网站欣赏/it培训机构怎么样
0.参考文献1.HashSet概述:HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。HashSet中不允许有重复元素,这是因为HashSet是基于HashMap实…...