首页 文章

Java - Groovy:将对象映射为键

提问于
浏览
2

我在如何从使用自定义对象索引的 Map 中检索值时遇到问题 . 在我的例子中,我有一个Map,其中Model对象为Key,对象List为Value . Map似乎填充得很好,因为我遍历每个Key并将所有Model对象打印到控制台 .

我的问题是如何从Map中的特定条目获取Value .

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() 以检索Map中该条目的列表?

UPDATE

这里是简单的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 回答

  • 4

    是的, Model 必须实现 hashCode()equals(Object) .

    ...如果可变对象用作 Map 键,则必须非常小心 . 如果在对象是 Map 中的键的情况下以影响等于比较的方式更改对象的值,则不指定映射的行为 . - 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 . 请注意,我假设您的意图,因此偏离您的示例来编码您所说的内容:

    ...一个Map,其中Model对象为Key,对象列为Value .

    EqualsAndHashCode 文档描述了如何调整默认行为,以备不时之需 .

相关问题