[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(用户类,即用户节点类的数据域),在这里就不再罗嗦了 :) 。
分享到:
相关推荐
java HashSet 集合排序,需要通过利用TreeSet集合排序。2013-10-30。
知识点1: HashSet集合的特点 HashSet集合是一种基于哈希表的集合实现,它的特点是: * 不存储重复元素 * 元素的顺序是随机的 * 查找、插入、删除元素的时间复杂度为O(1) 知识点2: HashSet集合的存储机制 HashSet...
本文将深入探讨HashSet类及其相关的知识点。 首先,HashSet是由HashMap内部实现的,它利用了键值对(key-value)的概念,但与HashMap不同的是,HashSet不存储值,而是直接使用键(key)作为存储元素。每个元素在...
在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。
在Java编程中,HashSet是一种不允许存储重复元素的集合,它实现了Set接口。HashSet是通过HashMap来实现的,其底层使用HashMap来保存所有元素。这种实现方式让HashSet的操作非常简单高效,因为HashSet的大部分操作,...
图文并茂,能让大家很好的理解java中这个重要的知识点。 此文档需要wps或者office软件来查看,如果你没有此软件,到http://www.wps.com.cn 下载wps即可查看此文档。 注:本人所有资源都是共享的,的资源分都是0!
在Java语言中,HashSet类是集合框架的重要组成部分,属于Set接口的一个实现。它基于哈希表的原理来存储不重复的元素,其核心在于利用哈希算法快速定位元素存储位置,从而提高数据存取的效率。本篇将详细介绍Java语言...
HashSet 是 Java 中的一个集合类,它实现了 Set 接口并提供了基于哈希表的无序、不重复元素的集合。具体来说,它是通过哈希表(实际上是一个 HashMap 实例)来存储元素的。 以下是 HashSet 的一些主要特点: 无序...
HashSet是Java编程语言中的一种集合类...然而,在多线程环境下,为了保证线程安全,可以使用`Collections.synchronizedSet`方法来包装HashSet,或者考虑使用ConcurrentHashMap来构建一个线程安全的集合并实现类似功能。
集合是Java编程中的一种核心概念,它是一种存储和管理对象的方式。在Java中,集合框架是Java.util包下的一个子集,提供了各种不同类型的集合,包括List、Map和Set等,用于满足不同的数据存储需求。 标题中的“集合...
HashSet作为Java集合框架中一个重要的非同步集合实现,它在JDK 7.0中的底层实现原理是基于HashMap来存储和操作数据的。下面就详细介绍HashSet的实现原理。 首先,HashSet是Set接口的一个实现类,它用于存储唯一性的...
- **`HashSet`与`ArraySet`/`LinkedSet`**:`HashSet`是基于哈希表实现的,而`ArraySet`通常是指数组实现的集合,`LinkedSet`则是基于链表实现的有序集合。`HashSet`提供了非常高效的增删查操作,但不保证元素的插入...
`HashSet`是Java集合框架的一部分,它实现了`Set`接口。`HashSet`不允许重复的元素,并且不保证元素的顺序。此外,`HashSet`是非同步的,这意味着多线程环境下的安全问题需要通过外部同步机制解决。 #### 二、特点 ...
掌握List集合、Set集合、Map集合的使用以及Iterator迭代器和foreach循环的使用 了解常用的集合类 熟悉泛型的使用
本篇将深入探讨List接口和Set集合,特别是LinkedList、HashSet以及Collection集合体系。\n\n1. **List接口**\n List接口是Java集合框架中的一员,它代表有序的、可重复的元素序列。List接口的主要特点是元素具有索引...
在 Java 中,集合框架是处理对象集合的重要工具。在第8天的学习中,主要涵盖了两种主要的集合类型:List 和 Set。List 和 Set 都属于 Collection 集合体系的一部分,但它们各自有着不同的特点和用途。 List 集合是...
通过实例学习Java集合框架HashSet HashSet是Java集合框架中的一种重要数据结构,用于存储不重复的元素。通过实例学习Java集合框架HashSet,可以帮助开发者更好地理解和使用HashSet,提高编程效率和代码质量。本文将...