とりあえず implements Map した

追記:
太一くんが添削してくれた
http://d.hatena.ne.jp/taichitaichi/20081229/1230544658
なるほど、スレッド立ててスケジューラに未来の削除を登録するのか!!
勉強になりまする!!


ありがとう id:taichitaichi !!
メインアカウント人気無いね」なんて言ってゴメン!!


clean() するタイミングは色々調整してみる><

/**
 * 
 */
package org.yoshiori.collection.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author yoshiori
 * 
 */
public class TimeLimitHashMap<K, V> implements Map<K, V>{


	private final Map<K, TimeAndValue> map = new HashMap<K, TimeAndValue>();
	private long timelimit = 5 * 60 * 1000;

	public TimeLimitHashMap() {
	}

	/**
	 * @param timelimit
	 */
	public TimeLimitHashMap(long timelimit) {
		this.timelimit = timelimit;
	}

	@SuppressWarnings("unchecked")
	public boolean containsValue(Object value) {
		clean();
		try {
			TimeAndValue timeAndValue = new TimeAndValue(new Date(), (V) value);
			return map.containsValue(timeAndValue);
		} catch (Exception e) {
			return false;
		}
	}


	public V get(Object key) {
		TimeAndValue timeAndValue = map.get(key);
		clean();
		if(timeAndValue != null){
			return timeAndValue.getValue();
		}
		return null;
	}

	public V put(K key, V value) {
		TimeAndValue timeAndValue = new TimeAndValue(new Date(), value);
		map.put(key, timeAndValue);
		clean();
		return value;
	}


	public V remove(Object key) {
		TimeAndValue timeAndValue = map.remove(key);
		clean();
		if(timeAndValue != null){
			return timeAndValue.getValue();
		}
		return null;
	}

	public void clear() {
		map.clear();
	}

	public boolean containsKey(Object key) {
		clean();
		return map.containsKey(key);
	}

	public Set<Entry<K, V>> entrySet() {
		clean();
		Set<Entry<K, V>> set = new HashSet<Entry<K, V>>();
		for(Entry<K, TimeAndValue> entry : map.entrySet()){
			set.add(new MyEntry<K,V>(entry.getKey(),entry.getValue().getValue()));
		}
		return set;
	}

	public boolean isEmpty() {
		clean();
		return map.isEmpty();
	}

	public Set<K> keySet() {
		clean();
		return map.keySet();
	}

	public void putAll(Map<? extends K,? extends V> m) {
		clean();
		for(Entry<? extends K, ? extends V> entry : m.entrySet()){
			map.put(entry.getKey(), new TimeAndValue(new Date(), entry.getValue()));
		}
	}

	public int size() {
		clean();
		return map.size();
	}

	public Collection<V> values() {
		clean();
		List<V> list = new ArrayList<V>();
		for(TimeAndValue value : map.values()){
			list.add(value.getValue());
		}
		return list;
	}
	
	private void clean(){
		for(TimeAndValue value : map.values()){
			if(checkTimeout(value.getTime())){
				map.remove(value);
			}
		}
	}
	
	public boolean checkTimeout(Date date){
		return System.currentTimeMillis() - date.getTime() > timelimit;
	}
	
	private class MyEntry<K, V> implements Entry<K, V>{
		private final K key;
		private V value;
		
		/**
		 * @param key
		 * @param value
		 */
		private MyEntry(K key, V value) {
			super();
			this.key = key;
			this.value = value;
		}

		public K getKey() {
			return key;
		}

		/* (non-Javadoc)
		 * @see java.util.Map.Entry#getValue()
		 */
		public V getValue() {
			return value;
		}

		/* (non-Javadoc)
		 * @see java.util.Map.Entry#setValue(java.lang.Object)
		 */
		public V setValue(V value) {
			this.value = value;
			return this.value;
		}
		
	}
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private class TimeAndValue {
		/**
		 * @param time
		 * @param value
		 */
		private TimeAndValue(Date time, V value) {
			this.time = time;
			this.value = value;
		}

		/**
		 * @return the time
		 */
		public Date getTime() {
			return time;
		}

		/**
		 * @return the value
		 */
		public V getValue() {
			return value;
		}

		private Date time;
		private V value;


		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((value == null) ? 0 : value.hashCode());
			return result;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			TimeAndValue other = (TimeAndValue) obj;
			if (value == null) {
				if (other.value != null)
					return false;
			} else if (!value.equals(other.value))
				return false;
			return true;
		}

	}
}