我在如何从使用自定义对象编制索引的地图中检索值时遇到问题。在我的例子中,我有一个Map,其中Model对象为Key,对象List为Value。 Map似乎填充得很好,因为我已遍历每个Key并将所有Model对象打印到控制台。
我的问题是如何从地图中的特定条目中获取价值。
Map<Model, Parameter> mapSet = m.getMyMap()
for(Entry<Model, Parameter> entry : mapSet){
println entry.key.getModel() //prints each Model
}
List<Parameter> testListBase = mapSet.get(new Model("BASE"))
List<Parameter> testListSearch = mapSet.get(new Model("SEARCH"))
我是否必须从Object覆盖hashCode()
和equals()
以检索地图中该条目的列表?
更新
这是简单的Model对象,但仍无法使用
检索密钥 mapSet.get(new Model("BASE"))
public final class Model {
private final String model;
private final static int count = 0;
private int id;
private Model(String model){
this.model = model;
id = ++count;
}
private String getModel(){
return model;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((model == null) ? 0 : model.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Model other = (Model) obj;
if (id != other.id) {
return false;
}
if (model == null) {
if (other.model != null) {
return false;
}
} else if (!model.equals(other.model)) {
return false;
}
return true;
}
}
答案 0 :(得分:4)
是的,Model
必须实施hashCode()
和equals(Object)
。
...如果可变对象用作地图键,则必须非常小心。 如果对象的值是,则不指定映射的行为 在对象中以一种影响等于比较的方式改变 是地图中的关键。 - http://docs.oracle.com/javase/7/docs/api/java/util/Map.html
您可以使用Groovy的EqualsAndHashCode AST转换轻松实现hashCode()
和equals(Object)
。这是一个有效的例子:
@groovy.transform.TupleConstructor
@groovy.transform.EqualsAndHashCode
class Model {
String name
}
@groovy.transform.TupleConstructor
class Parameter {
String name
}
Map<Model, List<Parameter>> mapSet = [
(new Model('BASE')): [
new Parameter('Some parameter'),
new Parameter('Another parameter')
],
(new Model('SEARCH')): [
new Parameter('Yet another parameter'),
new Parameter('And yet another parameter')
]
]
for(Map.Entry<Model, List<Parameter>> entry: mapSet) {
println entry.key // Prints each Model
}
List<Parameter> testListBase = mapSet.get(new Model("BASE"))
List<Parameter> testListSearch = mapSet.get(new Model("SEARCH"))
assert testListBase*.name.containsAll(['Some parameter', 'Another parameter'])
assert testListSearch*.name.containsAll(['Yet another parameter', 'And yet another parameter'])
为方便起见,我使用TupleConstructor
AST,但这里的工作是EqualsAndHashCode
。请注意,我假设您的意图,因此偏离您的示例来编码您所说的:
...一张地图,其中模型对象为关键字,对象列表为数值。
EqualsAndHashCode
文档介绍了如何根据需要调整默认行为。