java以object为键通过hashmap进行搜索
我在搜索各种主题,但没有找到任何适合我的情况的解决方案
假设我需要存储以下值: (1) 产品id(2)段id(3)某些价值
(1)和(2)的组合是独一无二的。为了明确起见,让我画一张简单的表格:
| product_id | segment_id | some_value|
---------------------------------------
| 1 | 1 | 100 |
| 1 | 2 | 200 |
| 2 | 1 | 300 |
| 2 | 2 | 400 |
我决定使用带有键的Map作为(1)和(2)的组合。实现该键的类如下(来自其他主题):
class MarketKey {
private final int x;
private final int y;
public MarketKey(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MarketKey)) return false;
MarketKey key = (MarketKey) o;
return x == key.x && y == key.y;
}
@Override
public int hashCode() {
int result = x;
result = 137 * result + y;
return result;
}
}
将值放到地图上效果非常好。现在,我想搜索这些键,并对特定的产品的值进行总结,这是键的一部分。如果我知道product_id和segment_id的范围,那就很容易了,但我不知道
我问自己的问题是地图是否是一个好的选择。我之所以选择它,是因为我想确保我不会有两个组合项,即product_id和segment_id,但这扼杀了我搜索密钥元素的能力
有没有关于如何实现这一点的提示
提前谢谢
编辑: 下面的一些答案指出,使用带有产品id的地图作为键。来自java文档:
A map cannot contain duplicate keys; each key can map to at most one value.
如果我的理解是正确的,product_id必须具有唯一的值,在我的示例中,情况并非如此
# 1 楼答案
你可以用一张地图。顶级映射使用
product_id
作为其键,每个成员映射使用segment_id
或者,您可以先基于
product_id
然后基于segment_id
定义键顺序,并使用SortedMap
SortedMap.subMap()
这样就可以方便地进行您描述的每种产品扫描更新:
对于这种任务,{}的主要优点是实现和使用简单。由
headMap()
、tailMap()
和subMap()
提供的submap视图可以作为一种方便的方式来处理OP呈现的问题类型:,但使用这种方法,您仍然可以通过一个键访问元素:
如果数据大小有一个固定的界限,或者这不是程序的性能关键部分,那么这几乎就是故事的结束。另一方面,如果程序需要执行诸如在其关键路径上描述的操作,并且如果数据可能非常大,则需要考虑性能。与{}或{}的
HashMap
相比,在SortedMap
上进行插入、单独检索和删除的平均性能(O(log n)
)的扩展效率更低。这是SortedMap
的排序性质的必然结果,而不取决于它的特定实现对于迭代具有给定产品ID的所有项目,行为如何缩放是一个更复杂的分析,部分取决于每个
product_id
的segment_id
数量如何缩放product_id
数量。不管怎样,与HashMap
的O(1)
相比,SortedMap
案例的第一个条目有O(log n)
成本,但在那之后,剩下的每一个都可以以固定的增量成本获得。如果段ID的数量与产品ID的数量成比例,那么遍历第二个和后续元素的成本占主导地位,并且在每种情况下,总体操作都是O(n)
。另一方面,如果段ID的数量是固定的,则HashMap
的情况总体上是O(1)
,而SortedMap
的情况是O(log n)
# 2 楼答案
Map
是一个不错的选择,但是使用Map<Integer, Map<Integer, Integer>>
是有意义的,其中外部映射的键是产品ID,内部映射的键是段ID要获得“一些价值”,你必须
(实际上,这比这要复杂一些,因为你需要检查
null
以避免NullPointerException
)优点是,您可以轻松地对特定产品id的值求和:
我相信番石榴有一个
Table
接口,可以减轻使用这种结构的痛苦,但我从未使用过它。也许值得一看