Java - Groovy:将对象映射为键

时间:2015-12-19 17:47:08

标签: java groovy

我在如何从使用自定义对象编制索引的地图中检索值时遇到问题。在我的例子中,我有一个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;
}

}

1 个答案:

答案 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文档介绍了如何根据需要调整默认行为。

相关问题