【问题标题】:Can Collection be used as an key in Hashmap java?Collection可以用作Hashmap java中的键吗?
【发布时间】:2018-04-06 22:13:23
【问题描述】:

我有以下场景(修改了一个比实际业务目的)。

  1. 我有一个程序可以预测一个人会摄入多少卡路里 根据某些属性,在接下来的 13 周内松动。
  2. 我想将此结果缓存在数据库中,这样我就不会调用 再次预测相同的组合。
  3. 我有班人 class Person { int personId; String weekStartDate; }
  4. 我有HashMap<List<Person>, Integer> - 关键是一个人13周的数据,值是预测
  5. 我会将哈希值保留在数据库中以用于缓存目的

有没有更好的方法来处理上述情况?任何支持此类场景的设计模式

【问题讨论】:

  • 我有 HashMap, Integer> - 关键是一个人的 13 周数据,值是预测 ---> 人对象不是真正的数据,对吗?因为它们只包含 personIds 和日期?
  • 另外,一个人的列表是一个人的 13 周数据,这对我来说似乎有点违反直觉。这本身就是一个很好的课程候选人。
  • 您的数据结构不正确。关键似乎是不同人的集合。一般来说,任何可变对象都不应用作 HashMap 中的键,因为对任何包含的值的任何更改都会破坏映射并阻止以后找到该对象。
  • HashMap< List < Person>, Integer>而言,是的,您可以这样做。
  • @FedericoklezCulloca,13 周是动态的,它取决于输入参数。在另一种情况下,它可以预测未来 6 周

标签: java design-patterns hashmap


【解决方案1】:

取决于:hashCode() 的实现使用列表的 元素。因此,稍后在更改该操作的结果时添加元素:

public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

地图不是为可以更改其哈希值的键构建的!当然,以不同的方式实现该方法并没有真正意义。

所以:当您的列表全部不可变时,它可以工作,这意味着列表及其任何成员都不会在之后被修改list 被用作键。但是存在一定的风险:如果您稍后忘记了那个合同,并且这些列表看到了修改,那么您将遇到有趣的问题。

【讨论】:

  • 元素是固定的,那个人对象仅用于密钥形成,我们将覆盖哈希码和等于。仍然会是一个糟糕的设计吗?
  • @i0707 它应该可以工作,但这个想法不是很强大。如果你曾经违反这个隐含的合同(很难执行),你会遇到各种奇怪的错误。
【解决方案2】:

这是可行的,因为标准 List 实现的哈希码是使用内容的哈希码计算的。但是,您需要确保在 Person 类中也实现 hashCodeequals,否则您将遇到相同的问题 this guy had。另请参阅我对该问题的回答。

【讨论】:

    【解决方案3】:

    我建议您定义一个类(例如Data)并将其用作哈希图中的键。使用数周内的数据知识相应地覆盖 equals/hashcode

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-26
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 2014-12-26
      • 2015-02-05
      • 2015-03-05
      相关资源
      最近更新 更多