`

对构建hashSet集合的几点见解

阅读更多

[size=medium][/size][color=blue][/color]
最近自己做了一类似于hashSet集合的小程序。该程序通过模仿法hashSet特征,同时也根据自己的一些需要自定义了一些格式内容放里面,实现了add()、search()、remove()等方法。好啦 !废话就少说啦,下面是我对hashSet的一些总结。欢迎各位大侠指点。。。

1.    HashSet概述:
   HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。
 
2.    HashSet的实现:
   对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成, HashSet的源代码如下:
Java代码 
 public class HashSet<E>  
     extends AbstractSet<E>  
     implements Set<E>, Cloneable, java.io.Serializable  
 {  
     static final long serialVersionUID = -5024744406713321676L;  
  
     // 底层使用HashMap来保存HashSet中所有元素。  
     private transient HashMap<E,Object> map;  
       
     // 定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。  
     private static final Object PRESENT = new Object();  
  
     /** 
      * 默认的无参构造器,构造一个空的HashSet。 
      *  
      * 实际底层会初始化一个空的HashMap,并使用默认初始容量为16和加载因子0.75。 
      */ 
     public HashSet() {  
     map = new HashMap<E,Object>();  
     }  
  
     /** 
      * 构造一个包含指定collection中的元素的新set。 
      * 
      * 实际底层使用默认的加载因子0.75和足以包含指定 
      * collection中所有元素的初始容量来创建一个HashMap。 
      * @param c 其中的元素将存放在此set中的collection。 
      */ 
     public HashSet(Collection<? extends E> c) {  
     map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));  
     addAll(c);  
     }  
  
     /** 
      * 以指定的initialCapacity和loadFactor构造一个空的HashSet。 
      * 
      * 实际底层以相应的参数构造一个空的HashMap。 
      * @param initialCapacity 初始容量。 
      * @param loadFactor 加载因子。 
      */ 
     public HashSet(int initialCapacity, float loadFactor) {  
     map = new HashMap<E,Object>(initialCapacity, loadFactor);  
     }  
  
     /** 
      * 以指定的initialCapacity构造一个空的HashSet。 
      * 
      * 实际底层以相应的参数及加载因子loadFactor为0.75构造一个空的HashMap。 
      * @param initialCapacity 初始容量。 
      */ 
     public HashSet(int initialCapacity) {  
     map = new HashMap<E,Object>(initialCapacity);  
     }  
  
3.以上是我参考了hashSet 源代码再结合自己的一些经验给出的几点看法。下面是我这次对hashSet的亲身体验:
/**
 * 主类  用来处理各种哈希事件
 * @author
 *
 */
public class HashMain {
 //定义一个具有初始长度的数组
 private  InfoNode[]  nodeArray = new InfoNode[300];
 public static int sum = 100;
 /**
  *  add()方法  添加用户
  */
 public void add(int i ,InfoNode node){
  int index = hashFuction(i);
  if(nodeArray[index]==null){//如果该索引位置的数组值为空
   nodeArray[index]=node;
  }else{
   InfoNode root = nodeArray[index];//根节点
   InfoNode next = root.getChild();//此时根节点的下一个节点
   root.setChildNode(node);//设置当前节点为子节点
   node.setFatherNode(root);
   if(next!=null){
    //root.getChild().setChildNode(next);
    node.setChildNode(next);
    next.setFatherNode(node);
   }
  }
 }
 /**
  * 定义一个查找用户的方法(根据用户名字)
  */
 public UserInfo search(String name){
  for(int i=0;i<nodeArray.length;i++){
   InfoNode root = nodeArray[i];
   if(root==null) continue;//如果该数组元素为空 则直接进入下一个循环
   while(root!=null){
    if(root.getInfo().getName().equals(name)){
     return root.getInfo();
    }
    root = root.getChild();
   }

  }
  return null;
 }
 /**
  * 重载一个查找用户的方法(根据编号)
  */
 public UserInfo search(int number){
  int index = hashFuction(number);//获得该元素在数组中的索引
  InfoNode root = nodeArray[index];
  while(root!=null){
   if(root.getInfo().getNum()==number){
    return root.getInfo();
   }
  }
  return null;
 }
 /**
  * 定义删除某一个用户的方法(根据该用户的名字)
  */
 public void remove(String name){
  for(int i=0;i<nodeArray.length;i++){
   InfoNode root = nodeArray[i];
   if(root==null) continue;//如果数组元素为空 则直接进行下一次循环
   //如果数组本省的元素就是要找的用户的话
   if(root.getInfo().getName().equals(name)){
    InfoNode next = root.getChild();
    if(next!=null){
     nodeArray[i]=next;
     System.out.println("删除了名为"+name+"的学生,该学生人气指数为:"+root.getInfo().getNum());
     break;
    }else{
     nodeArray[i]=null;
     System.out.println("删除了名为"+name+"的学生,该学生人气指数为:"+root.getInfo().getNum());
     break;
    }
   }
   //遍历整个数组以及数组中原所包含的所有节点
   while(root!=null){
    String userName = root.getInfo().getName();
    if(userName.equals(name)){
     InfoNode child = root.getChild();
     InfoNode father = root.getFather();
     if(child!=null){//如果当前root不是最后一个节点
      father.setChildNode(child);
      child.setFatherNode(father);
     }else{//如果当前root是链表末尾节点
      father.setChildNode(null);
     }
     System.out.println("删除了名为"+name+"的学生,该学生人气指数为:"+root.getInfo().getNum());
     break;
    }
    root = root.getChild();
   }
  }
 }
 /**
  * 哈希函数
  */
 public int hashFuction(int i){
  int index = i%(nodeArray.length-1);
  return index;

 }
 /**
  * 定义重建哈希集合的方法
  */
 public void reSetHash(){
  InfoNode[] reNodeArray = new InfoNode[sum];
  nodeArray = reNodeArray;//,新建一个数组指向原来的数组
  init();
 }
 /**
  * 打印数组的方法
  */
 public int printArray(){
  int count1=0;
  int count2=0;
  for(int i=0;i<nodeArray.length;i++){
   InfoNode nextNode = nodeArray[i];
   //遍历整个数组以及数组中原所包含的所有节点
   while(nextNode!=null){
    String name = nextNode.getInfo().getName();
    int number = nextNode.getInfo().getNum();
    System.out.println(name+"的人气指数是:"+number);
    nextNode = nextNode.getChild();
    count1++;
   }
   //遍历数组本身的元素
   if(nodeArray[i]!=null){
    count2++;
   } 
  }
  return count1-count2;//返回幅值
 }
 /**
  * 初始化数组
  * @param userArray
  */
 public void init(){
  for(int i=0;i<sum;i++){//循环创建用户对象
   int number = (int)(Math.random()*400);//产生随机数
   String name = "学生"+String.valueOf(i);
   UserInfo user = new UserInfo(number,name);
   InfoNode node = new InfoNode(user);
   add(number,node);//向数组中添加元素
  }

 }
 /**
  * 主类
  * @param args
  */
 public static void main(String[] args) {
  HashMain hash = new HashMain();
  hash.init();
  //***********************建立hash集合
  int count = hash.printArray();
  System.out.println("幅值为"+count);
  
  //***********************删除某个元素
  hash.remove("学生49");
  
  //***********************根据用户名查找某个元素(遍历查找)
  int time = (int) System.currentTimeMillis();
  UserInfo user = hash.search("学生56");
  int last = ((int) System.currentTimeMillis()-time)*1000;
  if(user!=null){
  System.out.println("查找到了"+user.getName()+"该学生的人气指数是:"+user.getNum()+"用时"+last);
  }else{
   System.out.println("该hash集合中没有要查找的元素!");
  }
  
  //***********************根据编号查找某个元素(索引查找)
  int time2 = (int) System.currentTimeMillis();
  UserInfo user2 = hash.search(278);
  int last2 = ((int) System.currentTimeMillis()-time2)*1000;
  if(user2!=null){
  System.out.println("查找到了"+user2.getName()+"该学生的人气指数是:"+user2.getNum()+"用时"+last2);
  }else{
   System.out.println("该hash集合中没有要查找的元素!");
  }
  
  //如果链表元素的数目太多则重建hash
  if(count>sum*(1.25)){
   hash.reSetHash();
   System.out.println("重建了hash集合!!!");
  }
 }
}

这是hashSet的主类,这段代码里面还包含大家最熟悉的InfoNode(用户节点类),以及UserInfo(用户类,即用户节点类的数据域),在这里就不再罗嗦了 :) 。

 


   

1
0
分享到:
评论

相关推荐

    NitroDioxide:我要学习的存储库,我随机制作的所有内容都在这里

    通过阅读和分析这些代码,你可以深入了解作者如何应用上述知识点,以及他们对Java编程的独特见解和实践技巧。此外,这样的存储库也是学习其他开发者解决问题的方式和代码风格的好途径,有助于提升自己的编程技能。

    观点

    4. **集合框架**:Java集合框架包括List(如ArrayList和LinkedList)、Set(如HashSet和TreeSet)、Map(如HashMap和TreeMap)等接口和实现类,它们提供了存储和操作对象的强大工具。 5. **多线程**:Java内置了对...

    java代码-12 杨建儒 第六题

    3. **数组和集合**:数组是存储固定数量相同类型元素的数据结构,而集合框架(如ArrayList、LinkedList、HashSet等)则提供了更灵活的数据存储和操作方式。 4. **函数(方法)**:将功能封装到独立的函数中,可以使...

    TinyYolo2实时视频流物体检测ONNX模型

    TinyYolo2实时视频流物体检测ONNX模型 运行 ONNX 模型,并结合 OpenCV 进行图像处理。具体流程包括: 1. 加载并初始化 ONNX 模型。 2. 从摄像头捕获实时视频流。 3. 对每一帧图像进行模型推理,生成物体检测结果。 4. 在界面上绘制检测结果的边界框和标签。

    chromedriver-linux64-134.0.6998.23(Beta).zip

    chromedriver-linux64-134.0.6998.23(Beta).zip

    Web开发:ABP框架4-DDD四层架构的详解

    Web开发:ABP框架4-DDD四层架构的详解

    chromedriver-linux64-135.0.7029.0(Canary).zip

    chromedriver-linux64-135.0.7029.0(Canary).zip

    (参考项目)MATLAB人脸门禁系统.zip

    实现人脸识别的考勤门禁系统可以分为以下步骤: 1. 采集人脸图像数据集:首先需要采集员工的人脸图像数据集,包括正面、侧面等多个角度的图像。可以使用MATLAB中的图像采集工具或者第三方库进行采集。 2. 预处理人脸图像数据:对采集到的人脸图像数据进行预处理,包括人脸检测、人脸对齐、人脸裁剪等操作。MATLAB提供了相关的图像处理工具箱,可以用于实现这些处理步骤。 3. 特征提取与特征匹配:使用人脸识别算法提取人脸图像的特征,比如使用人脸识别中常用的特征提取算法如Eigenfaces、Fisherfaces或者基于深度学习的算法。然后将员工的人脸数据与数据库中的人脸数据进行匹配,判断是否为注册员工。 4. 考勤记录与门禁控制:如果人脸匹配成功,系统可以记录员工的考勤时间,并且控制门禁系统进行开启。MATLAB可以与外部设备进行通信,实现门禁控制以及考勤记录功能。

    rdtyfv、ijij

    yugy

    企业IT治理体系规划.pptx

    企业IT治理体系规划.pptx

    基于Nutz、SSH、SSM的新闻管理系统.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    基于多目标粒子群算法的冷热电联供综合能源系统优化调度与运行策略分析,基于多目标粒子群算法的冷热电联供综合能源系统优化调度与运行策略分析,MATLAB代码:基于多目标粒子群算法冷热电联供综合能源系统运行

    基于多目标粒子群算法的冷热电联供综合能源系统优化调度与运行策略分析,基于多目标粒子群算法的冷热电联供综合能源系统优化调度与运行策略分析,MATLAB代码:基于多目标粒子群算法冷热电联供综合能源系统运行优化 关键词:综合能源 冷热电三联供 粒子群算法 多目标优化 参考文档:《基于多目标算法的冷热电联供型综合能源系统运行优化》 仿真平台:MATLAB 平台采用粒子群实现求解 优势:代码注释详实,适合参考学习,非目前烂大街的版本,程序非常精品,请仔细辨识 主要内容:代码构建了含冷、热、电负荷的冷热电联供型综合能源系统优化调度模型,考虑了燃气轮机、电制冷机、锅炉以及风光机组等资源,并且考虑与上级电网的购电交易,综合考虑了用户购电购热冷量的成本、CCHP收益以及成本等各种因素,从而实现CCHP系统的经济运行,求解采用的是MOPSO算法(多目标粒子群算法),求解效果极佳,具体可以看图 ,核心关键词: 综合能源系统; 冷热电三联供; 粒子群算法; 多目标优化; MOPSO算法; 优化调度模型; 燃气轮机; 电制冷机; 锅炉; 风光机组; 上级电网购售电交易。,基于多目标粒子群算法的CCHP综合

    DSP28379D串口升级方案:单核双核升级与Boot优化,C#上位机开发串口通信方案,DSP28379D串口升级方案:单核双核升级与Boot优化,C#上位机开发实现串口通信,DSP28379D串口升

    DSP28379D串口升级方案:单核双核升级与Boot优化,C#上位机开发串口通信方案,DSP28379D串口升级方案:单核双核升级与Boot优化,C#上位机开发实现串口通信,DSP28379D串口升级方案 单核双核升级,boot升级,串口方案。 上位机用c#开发。 ,DSP28379D; 串口升级方案; 单核双核升级; boot升级; 上位机C#开发,DSP28379D串口双核升级方案:Boot串口升级技术使用C#上位机开发

    基于ASP.NET MVC+三层架构和EntityFramework的微博门户网站项目.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    基于PLC的双层自动门控制:光电传感触发,有序开关与延时功能实现,附程序、画面及参考文档 ,基于PLC的双层自动门控制系统:精准控制,保障无尘环境;门间联动,智能安防新体验 ,基于plc的双层自动门控

    基于PLC的双层自动门控制:光电传感触发,有序开关与延时功能实现,附程序、画面及参考文档。,基于PLC的双层自动门控制系统:精准控制,保障无尘环境;门间联动,智能安防新体验。,基于plc的双层自动门控制系统,全部采用博途仿真完成,提供程序,画面,参考文档,详情见图。 实现功能(详见上方演示视频): ① 某房间要求尽可能地保持无尘,在通道上设置了两道电动门,门1和门2,可通过光电传感器自动完成门的打开和关闭。 门1和门2 不能同时打开。 ② 第 1 道门(根据出入方向不同,可能是门 1 或门 2),是由在通道外的开门者通过按开门按钮打开的,而第 2 道门(根据出入方向不同,可能是门 1 或门 2 )则是在打开的第 1 道门关闭后自动地打开的(也可以由通道内的人按开门按钮来打开第2 道门)。 这两道门都是在门开后,经过 3s 的延时而自动关闭的。 ③ 在门关闭期间,如果对应的光电传感器的信号被遮断,则门立即自动打开。 如果在门外或者在门内的开门者按对应的开门按钮时,立即打开。 ④ 出于安全方面的考虑,如果在通道内的某个人经过光电传感器时,对应的门已经打开,则通道外的开门者可以不按开门按钮。

    黑马程序员Java品达通用权限项目,基于SpringCloud SpringBoot 的微服务框架的权限管理解决方案.zip

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    DeepSeek+DeepResearch-让科研像聊天一样简单

    DeepSeek+DeepResearch——让科研像聊天一样简单 (1)DeepSeek如何做数据分析? (2)DeepSeek如何分析文件内容? (3)DeepSeek如何进行数据挖掘? (4)DeepSeek如何进行科学研究? (5)DeepSeek如何写综述? (6)DeepSeek如何进行数据可视化? (7)DeepSeek如何写作润色? (8)DeepSeek如何中英文互译? (9)DeepSeek如何做降重? (10)DeepSeek论文参考文献指令 (11)DeepSeek基础知识。

    基于springboot+uniapp实现的蛋糕商城小程序.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    jdepend-demo-2.9.1-10.el7.x64-86.rpm.tar.gz

    1、文件内容:jdepend-demo-2.9.1-10.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/jdepend-demo-2.9.1-10.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊

Global site tag (gtag.js) - Google Analytics