我实现了一个队列类,其中元素(使用ArrayList实现)应该是可更新的,并且我有一个HashMap实例变量来跟踪它们的索引,因此该函数不必迭代通过数组寻找要替换的对象。
我试图这样做:
public void update(T oldElement, T newElement) {
int index = map.get(oldElement);
map.put(newElement, index);
elements.set(index, newElement);
}
参数oldElement是对一个对象的引用,该对象肯定等于要替换的元素,但我意识到它们仍然是单独的对象,并且在我的HashMap中找不到oldElement,因为它不是那里的钥匙。我真的无法想到任何有关这方面的想法,我们将不胜感激。
HashMap看起来像这样:
private HashMap<T, Integer> map = new HashMap<T, Integer>();
编辑:方法updade由类外部的代码调用。
这是由于我的remove()方法中的一个错误。我没有意识到HashMap实际上使用了对象&#39;散列。
答案 0 :(得分:0)
您可以实现一个哈希函数,该哈希函数不存储实际密钥,而是存储哈希值,如果两个键值相等,则保证相等。这相当于在密钥类中实现.equals()
和.hashCode()
,但如果您不能这样做,那么这是一个可能的选择:
protected int calculateHash(T key) {
// Your hash calculation is done here, the hash function must guarantee
// that the hash value is equal when feed equal keys, for example
// suppose that the key object contains a getName() method:
return getName().hashCode();
}
并使用该方法访问地图,而不是元素值本身:
map.put(calculateHash(newElement), index);
和
map.get(calculateHash(element));
请注意,当密钥对象发生更改时,您不需要更新映射(只要它生成与旧映射相同的哈希码),只有在索引更改时才需要更新映射。
如果您能够在.hashCode()
课程中实施.equals()
和T
,则这一切都是不必要的。 Eclipse或其他IDE可以自动为您生成这些方法。实施.hashCode()
和.equals()
是处理集合的所有类的最佳做法,尤其是在您使用Set
和Map
时。
答案 1 :(得分:0)
为什么不简单地使用保证顺序的LinkedHashMap
,也可以删除/获取O(1)。
如果您只想存储对象本身,并且在配套对象中没有辅助会计信息,您也可以简单地使用LinkedHashSet
。
正如@EmirCalabuch所指出的那样,两个解决方案(以及你的解决方案)都要求同一个对象不会两次进入队列,并且对象已经正确实现了equals和hashCode方法。