`
xiaodpro
  • 浏览: 3045 次
  • 性别: Icon_minigender_1
  • 来自: 岳阳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

模拟HashMap类的实现

阅读更多
此例使用数组展示了HashMap的存储实现,刚学集合类框架,希望对初学者有所借鉴,帮助理解HashMap的用法等。此例不免有些许错误,还望各位高手指出。
package com.xiaodpro.util;

/**
 * 模拟HashMap类的实现
 * @author xiaodpro
 * 2010年3月9日
 */
public class MapSet<E,T> implements Set<E,T> {

	private Object[] value;   //键对应的键值
	private Object[] key;     //用户指定键
	private int increment;    //数组动态增加量
	
	/**
	 * 创建一个默认MapSet结构
	 */
	public MapSet() {
		// TODO Auto-generated constructor stub
		this(10);
	}
	
	/**
	 * 创建一个指定初始大小的MapSet结构
	 * 	<p>如果指定大小小于1的话将抛出IllegalArgumentException异常 
	 * @param initSize 初始大小
	 */
	public MapSet(int initSize){
		this(initSize, 10);
	}
	
	/**
	 * 创建一个指定初始大小及增长量的MapSet结构
	 * 	<p>如果初始大小小于1或者是增长量小于1的话将抛出IllegalArgumentException异常
	 * @param initSize 初始大小
	 * @param increment 增长量
	 */
	public MapSet(int initSize, int increment){
		//初始化各个成员变量
		if(initSize < 1 || increment < 1)
			throw new IllegalArgumentException();
			
		this.key = new Object[initSize];
		this.value = new Object[initSize];
		this.increment = increment;
	}

	/**
	 * 向MapSet对象中添加一个键
	 *  <p>如果索引超出当前元素的总数将抛出ArrayIndexOutOfBoundsException异常
	 *  <p>如果key值为null值将会抛出NullPointerException异常
	 *  <p>如果添加的键已经存在于MapSet集合中将会抛出IllegalArgumentException异常
	 * @param key 要添加的键
	 */
	public void add(E key) {
		// TODO Auto-generated method stub
		add(key,null);
	}

	/**
	 * 向MapSet对象中添加一项
	 *  <p>如果索引超出当前元素的总数将抛出ArrayIndexOutOfBoundsException异常
	 *  <p>如果key值为null值将会抛出NullPointerException异常
	 *  <p>如果添加的键已经存在于MapSet集合中将会抛出IllegalArgumentException异常
	 * @param key 要添加的键
	 * @param value 添加的键对应的值
	 */
	public void add(E key, T value) {
		// TODO Auto-generated method stub
		add(key, value, size());
	}
	
	/**
	 * 向MapSet对象的指定位置处添加一项
	 *  <p>如果索引超出当前元素的总数将抛出ArrayIndexOutOfBoundsException异常
	 *  <p>如果key值为null值将会抛出NullPointerException异常
	 *  <p>如果添加的键已经存在于MapSet集合中将会抛出IllegalArgumentException异常
	 * @param key 要添加的键
	 * @param value 键对应的值
	 * @param index 指定的索引
	 */
	public void add(E key, T value, int index){
		//如果添加的值为null值则抛出NullPointerException异常
		if(key == null)
			throw new NullPointerException();
		if(index < 0 || index > size())
			throw new ArrayIndexOutOfBoundsException();
		
		if(isFull()){
			//如果当前长度已达到末端则将当前数组中的数据复制到新的数组中去,并将当前key和value的引用指向新的数组
			Object[] keytmp = new Object[this.key.length + this.increment];
			Object[] valuetmp = new Object[this.key.length + this.increment];
			System.arraycopy(this.key, 0, keytmp, 0, this.key.length);
			this.key = keytmp;
			
			System.arraycopy(this.value, 0, valuetmp, 0, this.value.length);
			this.value = valuetmp;
			removeLast();
		}
		

		for(int j = 0; j < size(); j++){
			//如果存在相同的键值则抛出IllegalArgumentException异常
			if(this.key[j] == key)
				throw new IllegalArgumentException();
		}
		this.key[index] = key;
		this.value[index] = value;
	}

	/**
	 * 移除指定的键
	 *  <p>如果找不到该键将会抛出NullPointerException异常
	 * @param key 要移除的键
	 */
	public T remove(Object key) {
		// TODO Auto-generated method stub
		return delete(spider(key)).search(key);
	}
	
	/**
	 * 删除指定索引处的键
	 *  <p>如果找不到该键值将会抛出ArrayIndexOutOfBoundsException异常
	 * @param index 要删除的索引
	 * @return 被移除的键值
	 */
	@SuppressWarnings("unchecked")
	public MapSet<E,T> delete(int index){
		if(index < 0 || index > size())
			throw new ArrayIndexOutOfBoundsException();
		
		MapSet<E,T> map =  new MapSet<E,T>(1,1);
		map.add((E)key[index], (T)value[index]);
		
		System.arraycopy(key, index + 1, key, index, size() - index);
		System.arraycopy(value, index + 1, value, index, size() - index);
		return map;
	}
	
	/**
	 * 移除最头部的元素
	 *  <p>如果当前MapSet对象没有元素,则抛出NullPointerException异常
	 * @return 移除的元素
	 */
	@SuppressWarnings("unchecked")
	public T removeFirst(){
		if(isEmpty())
			throw new NullPointerException();
		T item = (T)value[0];
		value[0] = null;
		return item;
	}
	
	/**
	 * 移除最尾部的元素
	 *  <p>如果当前MapSet对象中没有元素,则抛出NullPointerException异常
	 * @return 移除的元素
	 */
	@SuppressWarnings("unchecked")
	public T removeLast(){
		if(isEmpty())
			throw new NullPointerException();
		T item = (T)value[size()-1];
		value[size() - 1] = null;
		return item;
	}

	/**
	 * 查找指定键对应的键值
	 * @param item 要查询的键
	 * @return 如果找到该键,则返回该键值;否则返回将抛出NullException异常
	 */
	@SuppressWarnings("unchecked")
	public T search(Object key) {
		// TODO Auto-generated method stub
		try {
			return (T) value[spider(key)];
		} catch (NullPointerException e) {
			// TODO: handle exception
			throw new NullPointerException();
		}
	}
	
	/**
	 * 获取指定索引处的键值
	 *  <p>如果指定的索引超出范围将会抛出ArrayIndexOutOfBoundsException异常
	 * @param index 指定的索引
	 * @return 指定索引处的键值
	 */
	@SuppressWarnings("unchecked")
	public MapSet<E,T> get(int index){
		if(index < 0 || index > size())
			throw new ArrayIndexOutOfBoundsException();
		MapSet<E,T> map = new MapSet<E,T>(1,1);
		map.add((E)key[index], (T)value[index]);
		return map;
	}

	/**
	 * 更新指定键的键值
	 *  <p>如果找不到指定的键将抛出NullPointerException异常
	 * @param key 要更新的键
	 * @param value 新的值
	 */
	public void updateValue(E key, T value) {
		// TODO Auto-generated method stub
		try {
			this.value[spider(key)] = value;
		} catch (NullPointerException e) {
			// TODO: handle exception
			throw new NullPointerException();
		}
	}
	
	private int spider(Object key) throws NullPointerException{
		//查找key键对应的索引,如果找不到该键则抛出NullPointerException异常
		for(int i = 0; i < size(); i++){
			if(this.key[i].equals(key)){
				return i;
			}
		}
		throw new NullPointerException();
	}
	
	/**
	 * 判断当前MapSet对象是否为空,如果为空则返回true,否则返回false
	 * @return 判断结果
	 */
	public boolean isEmpty(){
		if(this.size() == 0)
			return true;
		return false;
		
	}
	
	private boolean isFull(){
		//返回元素数组是否已满
		if(this.size() < this.key.length)
			return false;
		return true;
	}

	/**
	 * 清空当前MapSet对象
	 */
	public void clear() {
		// TODO Auto-generated method stub
		while(!isEmpty())
			key[size()-1] = null;
	}

	/**
	 * 获取当前MapSet对象的大小
	 * @return 当前MapSet对象的有效长度
	 */
	public int size() {
		// TODO Auto-generated method stub
		for(int i = this.key.length - 1; i >= 0; i--){
			if(this.key[i] != null)
				return i + 1;
		}
		return 0;
	}

}
分享到:
评论
1 楼 陈碧滔 2011-11-21  
消灭零回复!

相关推荐

    Java基础-模拟HashMap集合(基于数组和链表) 数组和链表.pdf

    我们将使用Java语言来模拟HashMap的实现。首先,我们需要定义一个接口MyMap,用于描述HashMap的基本操作: ```java public interface MyMap, V&gt; { void put(K key, V value); Object get(K key); void remove(K ...

    基于JavaScript的HashMap实现

    JavaScript本身并不直接支持HashMap,但我们可以利用对象(Object)的特性来模拟HashMap的实现。这篇博客“基于JavaScript的HashMap实现”可能详细阐述了如何通过自定义函数来创建一个高效且灵活的HashMap数据结构。...

    用HashMap模拟一个网上购物车

    ### 使用HashMap模拟网上购物车 #### 一、项目背景与目标 在本实验中,我们通过使用Java语言中的`HashMap`来模拟一个简单的网上购物车系统。该项目的主要目的是熟悉Java集合框架中的`HashMap`类,并了解如何利用它...

    枚举 HashMap

    下面我们将详细探讨如何使用HashMap实现枚举功能: 1. **枚举类的替代** 在Java中,枚举类可以定义一组常量,每个常量可以有自己的方法和属性。如果我们想模仿这个特性,可以在HashMap中存储键值对,键是代表枚举...

    HashMap介绍和使用

    这里的`Entry`是HashMap内部的一个静态类,用于存储键值对以及下一个节点的引用,构成链表: ```java static class Entry,V&gt; implements Map.Entry,V&gt; { final K key; V value; final int hash; Entry,V&gt; next;...

    js 版 java hashmap

    在JavaScript中,我们通常使用对象(Object)来模拟HashMap的行为,因为对象的属性名可以作为键,属性值则为对应的值。然而,这种模拟方式存在局限性,比如键必须是字符串或Symbol,且没有内置的方法来处理冲突。 ...

    一个基于js的HashMap

    在JavaScript中,我们通常会利用对象的属性访问特性来模拟HashMap的行为,因为对象的属性名本质上就是经过哈希处理的键。 1. **哈希函数**:一个良好的哈希函数能够将任何类型的键转化为整数,这个整数可以作为数组...

    javascript实现的HashMap类代码

    这个类使用了JavaScript对象来模拟HashMap的存储结构,其中对象的属性名作为键(key),属性值作为值(value)。 具体实现细节包括: - `this.size`:用于获取当前HashMap中键值对的数量。 - `this.clear`:用于...

    js 集合类实现 (HashMap, Set, ArrayList, etc.)

    在JavaScript中,虽然没有直接的HashMap实现,但我们可以利用`Object`来模拟这一功能。`Object`的键通常是字符串,但可以通过`Symbol`创建非字符串键,从而实现类似于哈希映射的行为。例如: ```javascript let ...

    页面算法模拟(java实现)

    1. **数据结构**:为了跟踪页面的访问状态,可以使用HashMap来存储页面与它们的最后一次访问时间,或者使用双向链表配合哈希表,链表存储页面顺序,哈希表用于快速查找。 2. **页面替换策略**:根据FIFO,只需维护...

    模拟实现Spring的IOC

    模拟实现__Spring的Ioc 1、Spring主要两个作用:实例化Bean,动态装配Bean。并将所有的bean放到spring容器中,调用时从容器中取。Spring容器就是一个bean的Map:private Map, Object&gt; beans = new HashMap, Object&gt;...

    java实现运用hashmap充当购物车goodbean充当存放数据.docx

    总之,这个Java实现利用HashMap和自定义的`GoodsBean`类,构建了一个简单的购物车系统,展示了如何在CS(Client-Server)架构中处理用户的购物行为,并与数据库进行交互存储和检索商品信息。通过这种方式,开发者...

    HashMap和链表的查找效率比较

    `List`接口有两个常见的实现类:`ArrayList`和`LinkedList`。`ArrayList`基于动态增长的数组实现,而`LinkedList`则是由双向链表构成。在`ArrayList`中,查找元素需要从头到尾遍历,时间复杂度为O(n);而`LinkedList...

    ArrayList和HashMap如何自己实现实例详解

    ArrayList和HashMap是Java编程语言中两种常用的集合类,它们分别实现了List接口和Map接口,用于存储和操作数据。在本实例中,我们将探讨如何自己实现这两个数据结构,以加深对它们工作原理的理解。 首先,ArrayList...

    ASP实现类似hashMap功能的类

    为了模拟HashMap的行为,我们定义了一个名为`Jb`的类。这个类包含以下关键属性和方法: - **arr**:二维数组,用于存储键值对数据。 - **arr_len**:表示键值对的数量。 - **putv**:用于添加或更新键值对。 - **...

    逆向-音乐学家方大刚-快速定位hashMap

    7. **重构逻辑**:一旦理解了HashMap的实现,可以尝试重构或模拟这个逻辑,以达到特定目的,如绕过安全检查、篡改数据或分析漏洞。 在这个过程中,音乐学家方大刚可能分享了一些独特的技巧或方法,帮助听众更高效地...

    自己写的一个随机数的例子,采用hashmap排序

    在描述中提到的博文链接可能提供了具体实现的细节,但在这里,我们可以假设代码的核心思路是生成一系列随机数,将它们与对应的权重(或其他信息)作为键值对存入HashMap,然后遍历HashMap来实现排序。由于HashMap...

    HashMap夺命连环问面试题分享给需要同学.docx

    模拟面试之HashMap ...\ 1.HashMap的底层数据结构是什么? 追问:为什么在1.8中增加红黑树? 追问:链表过深问题为什么不用二叉查找树代替,而选择红黑树?为什么不一直使用红黑树? 追问:讲一下你对红黑树的认识 2...

    JAVA实现类似C#的DataTable数据结构_适用于安卓

    在Java中,我们可以利用现有的数据结构,如ArrayList、HashMap或者自定义的数据结构来模拟DataTable的功能。例如,可以创建一个类,包含一个ArrayList来保存行数据,每一行又可以由一个HashMap表示,键为列名,值为...

    虚拟存储中页面调度算法LRU的模拟实现

    **实战应用**:在Java中,可以使用`java.util.LinkedList`和`java.util.HashMap`实现LRU算法。此外,还可以使用`java.util.PriorityQueue`来优化查找最近最少使用的页面,提高效率。 通过上述模拟,我们可以更好地...

Global site tag (gtag.js) - Google Analytics