追記:
太一くんが添削してくれた
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; } } }