我已经为键创建了一个带有.class对象的hashmap。
Hashmap<Class<? extends MyObject>, Object> mapping = new Hashmap<Class<? extends MyObject>, Object>();
这一切都很好,但是我得到了奇怪的行为,我只能用哈希函数归因于奇怪。在运行时期间随机迭代遍历hashmap不会命中每个值;它会错过一两个。我认为这可能是由于.class对象不是最终的,因此它会发生变化,导致它映射到不同的哈希值。使用不同的哈希值,哈希映射将无法正确地将密钥与值相关联,从而使其看起来已丢失该值。
我是否纠正这是怎么回事?我该如何解决这个问题?有没有更好的方法来完成这种形式的数据结构?
编辑:我真的以为我是在使用哈希函数的东西,但我会发布我的真实代码来试图解决这个问题。这可能是我实现多图的问题。我已经使用它已经有一段时间了,直到最近才发现任何问题。
/**
* My own implementation of a map that maps to a List. If the key is not present, then
* the map adds a List with a single entry. Every subsequent addition to the key
* is appended to the List.
* @author
*
* @param <T> Key
* @param <K> Value
*/
public class MultiMap<T, K> implements Map<T, List<K>>, Serializable, Iterable<K> {
/**
*
*/
private static final long serialVersionUID = 5789101682525659411L;
protected HashMap<T, List<K>> set = new HashMap<T, List<K>>();
@Override
public void clear() {
set = new HashMap<T, List<K>>();
}
@Override
public boolean containsKey(Object arg0) {
return set.containsKey(arg0);
}
@Override
public boolean containsValue(Object arg0) {
boolean output = false;
for(Iterator<List<K>> iter = set.values().iterator();iter.hasNext();) {
List<K> searchColl = iter.next();
for(Iterator<K> iter2 = searchColl.iterator(); iter2.hasNext();) {
K value = iter2.next();
if(value == arg0) {
output = true;
break;
}
}
}
return output;
}
@Override
public Set<Entry<T, List<K>>> entrySet() {
Set<Entry<T, List<K>>> output = new HashSet<Entry<T,List<K>>>();
for(Iterator<T> iter1 = set.keySet().iterator(); iter1.hasNext();) {
T key = iter1.next();
for(Iterator<K> iter2 = set.get(key).iterator(); iter2.hasNext();) {
K value = iter2.next();
List<K> input = new ArrayList<K>();
input.add(value);
output.add(new AbstractMap.SimpleEntry<T,List<K>>(key, input));
}
}
return output;
}
@Override
public boolean isEmpty() {
return set.isEmpty();
}
@Override
public Set<T> keySet() {
return set.keySet();
}
@Override
public int size() {
return set.size();
}
@Override
public Collection<List<K>> values() {
Collection<List<K>> values = new ArrayList<List<K>>();
for(Iterator<T> iter1 = set.keySet().iterator(); iter1.hasNext();) {
T key = iter1.next();
values.add(set.get(key));
}
return values;
}
@Override
public List<K> get(Object key) {
return set.get(key);
}
@Override
public List<K> put(T key, List<K> value) {
return set.put(key, value);
}
public void putValue(T key, K value) {
if(set.containsKey(key)) {
set.get(key).add(value);
}
else {
List<K> setval = new ArrayList<K>();
setval.add(value);
set.put(key, setval);
}
}
@Override
public List<K> remove(Object key) {
return set.remove(key);
}
public K removeValue(Object value) {
K valueRemoved = null;
for(T key:this.keySet()) {
for(K val:this.get(key)) {
if(val.equals(value)) {
List<K> temp = this.get(key);
temp.remove(value);
valueRemoved = val;
this.put(key, temp);
}
}
}
return valueRemoved;
}
@Override
public void putAll(Map<? extends T, ? extends List<K>> m) {
for(Iterator<? extends T> iter = m.keySet().iterator(); iter.hasNext();) {
T key = iter.next();
set.put(key, m.get(key));
}
}
@Override
public Iterator<K> iterator() {
return new MultiMapIterator<K>(this);
}
}
也许我的迭代器有问题?我也会发布那些代码。
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
public class MultiMapIterator<T> implements Iterator<T> {
private MultiMap <?, T> map;
private Iterator<List<T>> HashIter;
private Iterator<T> govIter;
private T value;
public MultiMapIterator(MultiMap<?, T> map) {
this.map = map;
HashIter = map.values().iterator();
if(HashIter.hasNext()) {
govIter = HashIter.next().iterator();
}
if(govIter.hasNext()) {
value = govIter.next();
}
}
@Override
public boolean hasNext() {
if (govIter.hasNext()) {
return true;
}
else if(HashIter.hasNext()) {
govIter = HashIter.next().iterator();
return this.hasNext();
}
else {
return false;
}
}
@Override
public T next() {
if(!this.hasNext()) {
throw new NoSuchElementException();
}
else {
value = govIter.next();
return value;
}
}
@Override
public void remove() {
map.remove(value);
}
}
很抱歉代码很长。感谢您花时间帮助我。
答案 0 :(得分:0)
您从构造函数中的govIter
中拉出一个值,但永远不会返回它。
你的迭代器删除方法是完全错误的。您正在迭代值,但调用由{em>键删除的map.remove
。你只想调用govIter.remove()
(除非你需要避免空列表,在这种情况下它更复杂)。
您的hasNext()方法也可能会出现问题,具体取决于您是否允许多地图中的空列表值。