使用跟踪索引的HashMap更新ArrayList中的元素

时间:2015-05-22 12:11:38

标签: java arraylist hashmap

我实现了一个队列类,其中元素(使用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;散列。

2 个答案:

答案 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()是处理集合的所有类的最佳做法,尤其是在您使用SetMap时。

答案 1 :(得分:0)

为什么不简单地使用保证顺序的LinkedHashMap,也可以删除/获取O(1)。

如果您只想存储对象本身,并且在配套对象中没有辅助会计信息,您也可以简单地使用LinkedHashSet

正如@EmirCalabuch所指出的那样,两个解决方案(以及你的解决方案)都要求同一个对象不会两次进入队列,并且对象已经正确实现了equals和hashCode方法。