Reputation: 63
I am having trouble on how to retrieve the Value from a Map indexed with custom Objects. In my case I have a Map with a Model object as Key and a List of objects as Value. The Map seems to be well populated because I've iterated through each Key and printed all Model objects to console.
My question is how to get Value from a specific entry in the Map.
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"))
Do I have to override hashCode()
and equals()
from Object to retrieve the list for that entry in the Map?
UPDATE
Here it is the simple Model object, but still cannot retrieve the key using
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;
}
}
Upvotes: 2
Views: 3287
Reputation: 9895
Yes, Model
must implement hashCode()
and equals(Object)
.
...great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map. - http://docs.oracle.com/javase/7/docs/api/java/util/Map.html
You may be able to implement hashCode()
and equals(Object)
quite easily using Groovy's EqualsAndHashCode AST transformation. Here's a working example:
@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'])
I used the TupleConstructor
AST for convenience, but the work-horse here is EqualsAndHashCode
. Note that I assumed your intention and therefore deviated from your example to code what you said:
...a Map with a Model object as Key and a List of objects as Value.
The EqualsAndHashCode
documentation describes how to tweak the default behaviour, in case you need to.
Upvotes: 4