模拟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;
}

}
import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * 购物车 */ public class Cart { //创建一个map对象,用来保存商品,key为商品,value为商品的数量 private Map<Goods, Integer> map = new HashMap<Goods, Integer>(); /** * 添加商品到购物车方法 * @param id 商品编号 * @param quantity 商品数量 */ public void addGoods(int id, int quantity){ Goods goods = GoodsDB.goodsMap.get(id); if(goods!=null){ Integer oQuantity = map.get(goods);//获取商品在购物车中原本的数量 if(oQuantity!=null){ oQuantity += quantity; }else{ oQuantity = quantity; } map.put(goods, oQuantity);//添加商品到map中 System.out.println("添加商品"+goods.getName()+"成功!"); }else{ System.out.println("添加失败!商品编号不存在!"); } } /** * 按指定的编号删除商品 * @param id 商品编号 */ public void delGoods(int id){ Goods goods = GoodsDB.goodsMap.get(id); if(goods!=null){ map.remove(goods);//从map删除商品 System.out.println("删除商品"+goods.getName()+"成功!"); }else{ System.out.println("删除失败!商品编号不存在!"); } } /** * 修改商品数量方法 * @param id 商品编号 * @param quantity 要修改的商品数量 */ public void updateGoods(int id, int quantity){ Goods goods = GoodsDB.goodsMap.get(id); if(goods!=null){ map.put(goods, quantity);//从map删除商品 }else{ System.out.println("修改失败!商品编号不存在!"); } } /** * 打印购物车商品列表 */ public void show(){ Set<Entry<Goods, Integer>> entrySet = map.entrySet(); System.out.println("编号\t单价\t数量\t名称\t总价"); for(Entry<Goods, Integer> entry:entrySet){ Goods goods = entry.getKey(); Integer quantity = entry.getValue(); System.out.println(goods.getId()+"\t"+goods.getPrice()+"\t"+quantity+"\t"+goods.getName()+"\t"+goods.getPrice()*quantity); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值