实现自己的ArrayList和HashMap

ArrayList的存储就是一个数组,


HashMap的存储是一个数组加一个链表,下面这张图来自: http://beyond99.blog.51cto.com/1469451/429789


以下实现的MyArrayList及MyHashMap,在实际的工作中都是用不上的,最有可能用得到的地方就是面试找工作以及忽悠别人了。工作中虽然用不上,但是并不代表没有用,它可以帮助我们去理解他们的实现原理,等实现完后再去仔细查看JDK中的源码,就会发现别人实现当中那些可供学习的地方。

MyArrayList

public class MyArrayList<E> {
	private int capacity = 10;
	private int size = 0;
	private E[] values = null;

	@SuppressWarnings("unchecked")
	public MyArrayList() {
		values = (E[]) new Object[capacity];
	}

	@SuppressWarnings("unchecked")
	public MyArrayList(int capacity) {
		this.capacity = capacity;
		values = (E[]) new Object[this.capacity];
	}

	public void put(E e) {
		if (e == null) {
			throw new RuntimeException("The value should not be null.");
		}
		if (size >= capacity) {
			enlargeCapacity();
		}
		values[size] = e;
		size++;
	}

	public E get(int index) {
		if (index >= size) {
			throw new RuntimeException("The index:" + index + " is out of band.");
		}
		return values[index];
	}

	public void remove(int index) {
		if (index >= size) {
			throw new RuntimeException("The index:" + index + " is out of band.");
		}
		for (int i = index; i < size - 1; i++) {
			values[i] = values[i + 1];
		}
		values[size - 1] = null;
		size--;
	}

	@SuppressWarnings("unchecked")
	private void enlargeCapacity() {
		capacity = capacity * 2;
		E[] tmpValues = (E[]) new Object[capacity];
		System.arraycopy(values, 0, tmpValues, 0, size);
		values = tmpValues;
	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		for (int i = 0; i < size; i++) {
			sb.append(values[i]).append(",");
		}
		if (size > 0) {
			sb.deleteCharAt(sb.length() - 1);
		}
		sb.append("]");
		return sb.toString();
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MyArrayList<String> myList = new MyArrayList<String>();
		myList.put("1");
		myList.put("2");
		myList.put("3");
		myList.put("4");
		myList.put("5");
		myList.put("6");
		myList.put("7");
		myList.put("8");
		myList.put("9");
		myList.remove(7);
		System.out.println(myList.toString());
	}

}

MyHashMap

public class MyHashMap<K, V> {
	//initialization capacity
	private int capacity = 10;
	//total entities
	private int size = 0;
	private Entity<K, V>[] entities = null;

	@SuppressWarnings("unchecked")
	public MyHashMap() {
		entities = new Entity[capacity];
	}

	public void put(K key, V value) {
		if (key == null) {
			throw new RuntimeException("The key is null");
		}
		reHash();
		Entity<K, V> newEntity = new Entity<K, V>(key, value);
		put(newEntity, this.entities, this.capacity);
	}

	private void put(Entity<K, V> newEntity, Entity<K, V>[] entities, int capacity) {
		int index = newEntity.getKey().hashCode() % capacity;
		Entity<K, V> entity = entities[index];
		Entity<K, V> firstEntity = entities[index];
		if (entity == null) {
			entities[index] = newEntity;
			size++;
		} else {
			if (newEntity.getKey().equals(entity.getKey())) {//Find the same key for the first entity, if find then replace the old value to new value
				newEntity.setNext(entity.getNext());
				newEntity.setPre(entity.getPre());
				if (entity.getNext() != null) {
					entity.getNext().setPre(newEntity);
				}
				entities[index] = newEntity;
			} else if (entity.getNext() != null) {
				while (entity.getNext() != null) {//Find the same key for all the next entity, if find then replace the old value to new value
					entity = entity.getNext();
					if (newEntity.getKey().equals(entity.getKey())) {
						newEntity.setPre(entity.getPre());
						newEntity.setNext(entity.getNext());
						if (entity.getNext() != null) {
							entity.getNext().setPre(newEntity);
						}
						entities[index] = newEntity;
						return;
					}
				}
				//Cannot find the same key, then insert the new entity at the header
				newEntity.setNext(firstEntity);
				newEntity.setPre(firstEntity.getPre());
				firstEntity.setPre(newEntity);
				entities[index] = newEntity;
				size++;
			} else {
				//Cannot find the same key, then put the new entity in head
				newEntity.setNext(firstEntity);
				firstEntity.setPre(newEntity);
				entities[index] = newEntity;
				size++;
			}
		}
	}

	public V get(K key) {
		if (key == null) {
			throw new RuntimeException("The key is null");
		}
		int index = key.hashCode() % capacity;
		Entity<K, V> entity = entities[index];
		if (entity != null) {
			if (entity.getKey().equals(key)) {
				return entity.getValue();
			} else {
				entity = entity.getNext();
				while (entity != null) {
					if (entity.getKey().equals(key)) {
						return entity.getValue();
					}
					entity = entity.getNext();
				}
			}

		}
		return null;
	}

	public void remove(K key) {
		if (key == null) {
			throw new RuntimeException("The key is null");
		}
		int index = key.hashCode() % capacity;
		Entity<K, V> entity = entities[index];
		if (entity != null) {
			if (entity.getKey().equals(key)) {
				if (entity.getNext() != null) {//remove the first entity
					entity.getNext().setPre(entity.getPre());
					entities[index] = entity.getNext();
					entity = null;
				} else {//empty this index
					entities[index] = null;
				}
				size--;
			} else {
				entity = entity.getNext();
				while (entity != null) {
					if (entity.getKey().equals(key)) {
						if (entity.getNext() != null) {
							entity.getPre().setNext(entity.getNext());
							entity.getNext().setPre(entity.getPre());
							entity = null;
						} else {
							//release the found entity
							entity.getPre().setNext(null);
							entity = null;
						}
						size--;
						return;
					}
					entity = entity.getNext();
				}
			}
		}
	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < capacity; i++) {
			sb.append("index=").append(i).append("[");
			boolean hasEntity = false;
			Entity<K, V> entity = entities[i];
			if (entity != null) {
				hasEntity = true;
			}
			while (entity != null) {
				sb.append("[").append(entity.getKey()).append("=").append(entity.getValue()).append("]").append(",");
				entity = entity.getNext();
			}
			if (hasEntity) {
				sb.deleteCharAt(sb.length() - 1);
			}
			sb.append("]\n");
		}
		return sb.toString();
	}

	/**
	 * Simple re-hash strategy, if the size is bigger than capacity, then do re-hash action
	 */
	private void reHash() {
		if (size >= capacity) {
			int newCapacity = capacity * 2;
			@SuppressWarnings("unchecked")
			Entity<K, V>[] newEntities = new Entity[newCapacity];
			for (int i = 0; i < capacity; i++) {
				Entity<K, V> entity = entities[i];
				while (entity != null) {
					put(entity, newEntities, newCapacity);
					entity = entity.getNext();
				}
			}
			this.capacity = newCapacity;
			this.entities = newEntities;
		}
	}

	public static void main(String[] args) {
		MyHashMap<String, String> map = new MyHashMap<String, String>();
		map.put("one", "1");
		map.put("two", "2");
		map.put("three", "3");
		map.put("four", "4");
		map.put("five", "5");
		map.put("six", "6");
		map.put("seven", "7");
		map.put("eight", "8");
		map.put("nine", "9");
		map.put("ten", "10");
		System.out.println(map.get("one"));
		System.out.println(map.get("two"));
		System.out.println(map.get("three"));
		System.out.println(map.get("four"));
		System.out.println(map.get("five"));
		System.out.println(map.get("six"));
		System.out.println(map.get("seven"));
		System.out.println(map.get("eight"));
		System.out.println(map.get("nine"));
		System.out.println(map.get("ten"));
		System.out.println(map.toString());

		map.remove("nine");
		map.remove("three");
		System.out.println(map.get("one"));
		System.out.println(map.get("two"));
		System.out.println(map.get("three"));
		System.out.println(map.get("four"));
		System.out.println(map.get("five"));
		System.out.println(map.get("six"));
		System.out.println(map.get("seven"));
		System.out.println(map.get("eight"));
		System.out.println(map.get("nine"));
		System.out.println(map.get("ten"));
		System.out.println(map.toString());
	}
}

class Entity<K, V> {
	private K key;
	private V value;
	private Entity<K, V> pre;
	private Entity<K, V> next;

	public Entity(K key, V value) {
		this.key = key;
		this.value = value;
	}

	public K getKey() {
		return key;
	}

	public void setKey(K key) {
		this.key = key;
	}

	public V getValue() {
		return value;
	}

	public void setValue(V value) {
		this.value = value;
	}

	public Entity<K, V> getPre() {
		return pre;
	}

	public void setPre(Entity<K, V> pre) {
		this.pre = pre;
	}

	public Entity<K, V> getNext() {
		return next;
	}

	public void setNext(Entity<K, V> next) {
		this.next = next;
	}

}



评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值